2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import com.android.internal.telephony.TelephonyIntents;
20 import com.google.android.collect.Lists;
21 import com.google.android.collect.Maps;
22 import com.android.internal.R;
23 import com.android.internal.annotations.GuardedBy;
24 import com.android.internal.app.AssistUtils;
25 import com.android.internal.app.DumpHeapActivity;
26 import com.android.internal.app.IAppOpsCallback;
27 import com.android.internal.app.IAppOpsService;
28 import com.android.internal.app.IVoiceInteractor;
29 import com.android.internal.app.ProcessMap;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.app.procstats.ProcessStats;
32 import com.android.internal.os.BackgroundThread;
33 import com.android.internal.os.BatteryStatsImpl;
34 import com.android.internal.os.IResultReceiver;
35 import com.android.internal.os.ProcessCpuTracker;
36 import com.android.internal.os.TransferPipe;
37 import com.android.internal.os.Zygote;
38 import com.android.internal.os.InstallerConnection.InstallerException;
39 import com.android.internal.util.ArrayUtils;
40 import com.android.internal.util.FastPrintWriter;
41 import com.android.internal.util.FastXmlSerializer;
42 import com.android.internal.util.MemInfoReader;
43 import com.android.internal.util.Preconditions;
44 import com.android.server.AppOpsService;
45 import com.android.server.AttributeCache;
46 import com.android.server.DeviceIdleController;
47 import com.android.server.IntentResolver;
48 import com.android.server.LocalServices;
49 import com.android.server.LockGuard;
50 import com.android.server.ServiceThread;
51 import com.android.server.SystemService;
52 import com.android.server.SystemServiceManager;
53 import com.android.server.Watchdog;
54 import com.android.server.am.ActivityStack.ActivityState;
55 import com.android.server.firewall.IntentFirewall;
56 import com.android.server.pm.Installer;
57 import com.android.server.statusbar.StatusBarManagerInternal;
58 import com.android.server.vr.VrManagerInternal;
59 import com.android.server.wm.WindowManagerService;
61 import org.xmlpull.v1.XmlPullParser;
62 import org.xmlpull.v1.XmlPullParserException;
63 import org.xmlpull.v1.XmlSerializer;
65 import android.Manifest;
66 import android.Manifest.permission;
67 import android.annotation.NonNull;
68 import android.annotation.UserIdInt;
69 import android.app.Activity;
70 import android.app.ActivityManager;
71 import android.app.ActivityManager.RunningTaskInfo;
72 import android.app.ActivityManager.StackId;
73 import android.app.ActivityManager.StackInfo;
74 import android.app.ActivityManager.TaskThumbnailInfo;
75 import android.app.ActivityManagerInternal;
76 import android.app.ActivityManagerInternal.SleepToken;
77 import android.app.ActivityManagerNative;
78 import android.app.ActivityOptions;
79 import android.app.ActivityThread;
80 import android.app.AlertDialog;
81 import android.app.AppGlobals;
82 import android.app.AppOpsManager;
83 import android.app.ApplicationErrorReport;
84 import android.app.ApplicationThreadNative;
85 import android.app.BroadcastOptions;
86 import android.app.Dialog;
87 import android.app.IActivityContainer;
88 import android.app.IActivityContainerCallback;
89 import android.app.IActivityController;
90 import android.app.IAppTask;
91 import android.app.IApplicationThread;
92 import android.app.IInstrumentationWatcher;
93 import android.app.INotificationManager;
94 import android.app.IProcessObserver;
95 import android.app.IServiceConnection;
96 import android.app.IStopUserCallback;
97 import android.app.ITaskStackListener;
98 import android.app.IUiAutomationConnection;
99 import android.app.IUidObserver;
100 import android.app.IUserSwitchObserver;
101 import android.app.Instrumentation;
102 import android.app.Notification;
103 import android.app.NotificationManager;
104 import android.app.PendingIntent;
105 import android.app.ProfilerInfo;
106 import android.app.admin.DevicePolicyManager;
107 import android.app.assist.AssistContent;
108 import android.app.assist.AssistStructure;
109 import android.app.backup.IBackupManager;
110 import android.app.usage.UsageEvents;
111 import android.app.usage.UsageStatsManagerInternal;
112 import android.appwidget.AppWidgetManager;
113 import android.content.ActivityNotFoundException;
114 import android.content.BroadcastReceiver;
115 import android.content.ClipData;
116 import android.content.ComponentCallbacks2;
117 import android.content.ComponentName;
118 import android.content.ContentProvider;
119 import android.content.ContentResolver;
120 import android.content.Context;
121 import android.content.DialogInterface;
122 import android.content.IContentProvider;
123 import android.content.IIntentReceiver;
124 import android.content.IIntentSender;
125 import android.content.Intent;
126 import android.content.IntentFilter;
127 import android.content.IntentSender;
128 import android.content.pm.ActivityInfo;
129 import android.content.pm.ApplicationInfo;
130 import android.content.pm.ConfigurationInfo;
131 import android.content.pm.IPackageDataObserver;
132 import android.content.pm.IPackageManager;
133 import android.content.pm.InstrumentationInfo;
134 import android.content.pm.PackageInfo;
135 import android.content.pm.PackageManager;
136 import android.content.pm.PackageManager.NameNotFoundException;
137 import android.content.pm.PackageManagerInternal;
138 import android.content.pm.ParceledListSlice;
139 import android.content.pm.PathPermission;
140 import android.content.pm.PermissionInfo;
141 import android.content.pm.ProviderInfo;
142 import android.content.pm.ResolveInfo;
143 import android.content.pm.ServiceInfo;
144 import android.content.pm.UserInfo;
145 import android.content.res.CompatibilityInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Bitmap;
150 import android.graphics.Point;
151 import android.graphics.Rect;
152 import android.location.LocationManager;
153 import android.net.Proxy;
154 import android.net.ProxyInfo;
155 import android.net.Uri;
156 import android.os.BatteryStats;
157 import android.os.Binder;
158 import android.os.Build;
159 import android.os.Bundle;
160 import android.os.Debug;
161 import android.os.DropBoxManager;
162 import android.os.Environment;
163 import android.os.FactoryTest;
164 import android.os.FileObserver;
165 import android.os.FileUtils;
166 import android.os.Handler;
167 import android.os.IBinder;
168 import android.os.IPermissionController;
169 import android.os.IProcessInfoService;
170 import android.os.IProgressListener;
171 import android.os.LocaleList;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PersistableBundle;
177 import android.os.PowerManager;
178 import android.os.PowerManagerInternal;
179 import android.os.Process;
180 import android.os.RemoteCallbackList;
181 import android.os.RemoteException;
182 import android.os.ResultReceiver;
183 import android.os.ServiceManager;
184 import android.os.StrictMode;
185 import android.os.SystemClock;
186 import android.os.SystemProperties;
187 import android.os.Trace;
188 import android.os.TransactionTooLargeException;
189 import android.os.UpdateLock;
190 import android.os.UserHandle;
191 import android.os.UserManager;
192 import android.os.WorkSource;
193 import android.provider.Downloads;
194 import android.os.storage.IMountService;
195 import android.os.storage.MountServiceInternal;
196 import android.os.storage.StorageManager;
197 import android.provider.Settings;
198 import android.service.voice.IVoiceInteractionSession;
199 import android.service.voice.VoiceInteractionManagerInternal;
200 import android.service.voice.VoiceInteractionSession;
201 import android.telecom.TelecomManager;
202 import android.text.format.DateUtils;
203 import android.text.format.Time;
204 import android.text.style.SuggestionSpan;
205 import android.util.ArrayMap;
206 import android.util.ArraySet;
207 import android.util.AtomicFile;
208 import android.util.DebugUtils;
209 import android.util.DisplayMetrics;
210 import android.util.EventLog;
211 import android.util.Log;
212 import android.util.Pair;
213 import android.util.PrintWriterPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.TimeUtils;
217 import android.util.Xml;
218 import android.view.Display;
219 import android.view.Gravity;
220 import android.view.LayoutInflater;
221 import android.view.View;
222 import android.view.WindowManager;
225 import java.io.FileDescriptor;
226 import java.io.FileInputStream;
227 import java.io.FileNotFoundException;
228 import java.io.FileOutputStream;
229 import java.io.IOException;
230 import java.io.InputStreamReader;
231 import java.io.PrintWriter;
232 import java.io.StringWriter;
233 import java.lang.ref.WeakReference;
234 import java.nio.charset.StandardCharsets;
235 import java.util.ArrayList;
236 import java.util.Arrays;
237 import java.util.Collections;
238 import java.util.Comparator;
239 import java.util.HashMap;
240 import java.util.HashSet;
241 import java.util.Iterator;
242 import java.util.List;
243 import java.util.Locale;
244 import java.util.Map;
245 import java.util.Objects;
246 import java.util.Set;
247 import java.util.concurrent.atomic.AtomicBoolean;
248 import java.util.concurrent.atomic.AtomicLong;
250 import dalvik.system.VMRuntime;
252 import libcore.io.IoUtils;
253 import libcore.util.EmptyArray;
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270 import static android.content.pm.PackageManager.GET_PROVIDERS;
271 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
273 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
274 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278 import static android.os.Process.PROC_CHAR;
279 import static android.os.Process.PROC_OUT_LONG;
280 import static android.os.Process.PROC_PARENS;
281 import static android.os.Process.PROC_SPACE_TERM;
282 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283 import static android.provider.Settings.Global.DEBUG_APP;
284 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289 import static android.provider.Settings.System.FONT_SCALE;
290 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.readIntAttribute;
292 import static com.android.internal.util.XmlUtils.readLongAttribute;
293 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294 import static com.android.internal.util.XmlUtils.writeIntAttribute;
295 import static com.android.internal.util.XmlUtils.writeLongAttribute;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372 import static org.xmlpull.v1.XmlPullParser.START_TAG;
374 public final class ActivityManagerService extends ActivityManagerNative
375 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
377 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386 private static final String TAG_LRU = TAG + POSTFIX_LRU;
387 private static final String TAG_MU = TAG + POSTFIX_MU;
388 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389 private static final String TAG_POWER = TAG + POSTFIX_POWER;
390 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393 private static final String TAG_PSS = TAG + POSTFIX_PSS;
394 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396 private static final String TAG_STACK = TAG + POSTFIX_STACK;
397 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
403 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404 // here so that while the job scheduler can depend on AMS, the other way around
405 // need not be the case.
406 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
408 /** Control over CPU and battery monitoring */
409 // write battery stats every 30 minutes.
410 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411 static final boolean MONITOR_CPU_USAGE = true;
412 // don't sample cpu less than every 5 seconds.
413 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414 // wait possibly forever for next cpu sample.
415 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416 static final boolean MONITOR_THREAD_CPU_USAGE = false;
418 // The flags that are set for all calls we make to the package manager.
419 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
421 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
423 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
425 // Amount of time after a call to stopAppSwitches() during which we will
426 // prevent further untrusted switches from happening.
427 static final long APP_SWITCH_DELAY_TIME = 5*1000;
429 // How long we wait for a launched process to attach to the activity manager
430 // before we decide it's never going to come up for real.
431 static final int PROC_START_TIMEOUT = 10*1000;
432 // How long we wait for an attached process to publish its content providers
433 // before we decide it must be hung.
434 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
436 // How long we will retain processes hosting content providers in the "last activity"
437 // state before allowing them to drop down to the regular cached LRU list. This is
438 // to avoid thrashing of provider processes under low memory situations.
439 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
441 // How long we wait for a launched process to attach to the activity manager
442 // before we decide it's never going to come up for real, when the process was
443 // started with a wrapper for instrumentation (such as Valgrind) because it
444 // could take much longer than usual.
445 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
447 // How long to wait after going idle before forcing apps to GC.
448 static final int GC_TIMEOUT = 5*1000;
450 // The minimum amount of time between successive GC requests for a process.
451 static final int GC_MIN_INTERVAL = 60*1000;
453 // The minimum amount of time between successive PSS requests for a process.
454 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
456 // The minimum amount of time between successive PSS requests for a process
457 // when the request is due to the memory state being lowered.
458 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
460 // The rate at which we check for apps using excessive power -- 15 mins.
461 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
463 // The minimum sample duration we will allow before deciding we have
464 // enough data on wake locks to start killing things.
465 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
467 // The minimum sample duration we will allow before deciding we have
468 // enough data on CPU usage to start killing things.
469 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
471 // How long we allow a receiver to run before giving up on it.
472 static final int BROADCAST_FG_TIMEOUT = 10*1000;
473 static final int BROADCAST_BG_TIMEOUT = 60*1000;
475 // How long we wait until we timeout on key dispatching.
476 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
478 // How long we wait until we timeout on key dispatching during instrumentation.
479 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
481 // This is the amount of time an app needs to be running a foreground service before
482 // we will consider it to be doing interaction for usage stats.
483 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
485 // Maximum amount of time we will allow to elapse before re-reporting usage stats
486 // interaction with foreground processes.
487 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
489 // This is the amount of time we allow an app to settle after it goes into the background,
490 // before we start restricting what it can do.
491 static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
493 // How long to wait in getAssistContextExtras for the activity and foreground services
494 // to respond with the result.
495 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
497 // How long top wait when going through the modern assist (which doesn't need to block
498 // on getting this result before starting to launch its UI).
499 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
501 // Maximum number of persisted Uri grants a package is allowed
502 static final int MAX_PERSISTED_URI_GRANTS = 128;
504 static final int MY_PID = Process.myPid();
506 static final String[] EMPTY_STRING_ARRAY = new String[0];
508 // How many bytes to write into the dropbox log before truncating
509 static final int DROPBOX_MAX_SIZE = 192 * 1024;
510 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511 // as one line, but close enough for now.
512 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
514 // Access modes for handleIncomingUser.
515 static final int ALLOW_NON_FULL = 0;
516 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517 static final int ALLOW_FULL_ONLY = 2;
519 // Delay in notifying task stack change listeners (in millis)
520 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
522 // Necessary ApplicationInfo flags to mark an app as persistent
523 private static final int PERSISTENT_MASK =
524 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
526 // Intent sent when remote bugreport collection has been completed
527 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528 "android.intent.action.REMOTE_BUGREPORT_FINISHED";
530 // Delay to disable app launch boost
531 static final int APP_BOOST_MESSAGE_DELAY = 3000;
532 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533 static final int APP_BOOST_TIMEOUT = 2500;
535 // Used to indicate that a task is removed it should also be removed from recents.
536 private static final boolean REMOVE_FROM_RECENTS = true;
537 // Used to indicate that an app transition should be animated.
538 static final boolean ANIMATE = true;
540 // Determines whether to take full screen screenshots
541 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542 public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
544 private static native int nativeMigrateToBoost();
545 private static native int nativeMigrateFromBoost();
546 private boolean mIsBoosted = false;
547 private long mBoostStartTime = 0;
549 /** All system services */
550 SystemServiceManager mSystemServiceManager;
552 private Installer mInstaller;
554 /** Run all ActivityStacks through this */
555 final ActivityStackSupervisor mStackSupervisor;
557 final ActivityStarter mActivityStarter;
559 /** Task stack change listeners. */
560 private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561 new RemoteCallbackList<ITaskStackListener>();
563 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
565 public IntentFirewall mIntentFirewall;
567 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568 // default actuion automatically. Important for devices without direct input
570 private boolean mShowDialogs = true;
571 private boolean mInVrMode = false;
573 // Whether we should use SCHED_FIFO for UI and RenderThreads.
574 private boolean mUseFifoUiScheduling = false;
576 BroadcastQueue mFgBroadcastQueue;
577 BroadcastQueue mBgBroadcastQueue;
578 // Convenient for easy iteration over the queues. Foreground is first
579 // so that dispatch of foreground broadcasts gets precedence.
580 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
582 BroadcastStats mLastBroadcastStats;
583 BroadcastStats mCurBroadcastStats;
585 BroadcastQueue broadcastQueueForIntent(Intent intent) {
586 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588 "Broadcast intent " + intent + " on "
589 + (isFg ? "foreground" : "background") + " queue");
590 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
594 * Activity we have told the window manager to have key focus.
596 ActivityRecord mFocusedActivity = null;
599 * User id of the last activity mFocusedActivity was set to.
601 private int mLastFocusedUserId;
604 * If non-null, we are tracking the time the user spends in the currently focused app.
606 private AppTimeTracker mCurAppTimeTracker;
609 * List of intents that were used to start the most recent tasks.
611 final RecentTasks mRecentTasks;
614 * For addAppTask: cached of the last activity component that was added.
616 ComponentName mLastAddedTaskComponent;
619 * For addAppTask: cached of the last activity uid that was added.
621 int mLastAddedTaskUid;
624 * For addAppTask: cached of the last ActivityInfo that was added.
626 ActivityInfo mLastAddedTaskActivity;
629 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
631 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
634 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
636 String mDeviceOwnerName;
638 final UserController mUserController;
640 final AppErrors mAppErrors;
642 boolean mDoingSetFocusedActivity;
644 public boolean canShowErrorDialogs() {
645 return mShowDialogs && !mSleeping && !mShuttingDown
646 && mLockScreenShown != LOCK_SCREEN_SHOWN;
649 private static final class PriorityState {
650 // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
651 // the current thread is currently in. When it drops down to zero, we will no longer boost
652 // the thread's priority.
653 private int regionCounter = 0;
655 // The thread's previous priority before boosting.
656 private int prevPriority = Integer.MIN_VALUE;
659 static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
660 @Override protected PriorityState initialValue() {
661 return new PriorityState();
665 static void boostPriorityForLockedSection() {
666 int tid = Process.myTid();
667 int prevPriority = Process.getThreadPriority(tid);
668 PriorityState state = sThreadPriorityState.get();
669 if (state.regionCounter == 0 && prevPriority > -2) {
670 state.prevPriority = prevPriority;
671 Process.setThreadPriority(tid, -2);
673 state.regionCounter++;
676 static void resetPriorityAfterLockedSection() {
677 PriorityState state = sThreadPriorityState.get();
678 state.regionCounter--;
679 if (state.regionCounter == 0 && state.prevPriority > -2) {
680 Process.setThreadPriority(Process.myTid(), state.prevPriority);
684 public class PendingAssistExtras extends Binder implements Runnable {
685 public final ActivityRecord activity;
686 public final Bundle extras;
687 public final Intent intent;
688 public final String hint;
689 public final IResultReceiver receiver;
690 public final int userHandle;
691 public boolean haveResult = false;
692 public Bundle result = null;
693 public AssistStructure structure = null;
694 public AssistContent content = null;
695 public Bundle receiverExtras;
697 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
699 activity = _activity;
703 receiver = _receiver;
704 receiverExtras = _receiverExtras;
705 userHandle = _userHandle;
709 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710 synchronized (this) {
714 pendingAssistExtrasTimedOut(this);
718 final ArrayList<PendingAssistExtras> mPendingAssistExtras
719 = new ArrayList<PendingAssistExtras>();
722 * Process management.
724 final ProcessList mProcessList = new ProcessList();
727 * All of the applications we currently have running organized by name.
728 * The keys are strings of the application package name (as
729 * returned by the package manager), and the keys are ApplicationRecord
732 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
735 * Tracking long-term execution of processes to look for abuse and other
738 final ProcessStatsService mProcessStats;
741 * The currently running isolated processes.
743 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
746 * Counter for assigning isolated process uids, to avoid frequently reusing the
749 int mNextIsolatedProcessUid = 0;
752 * The currently running heavy-weight process, if any.
754 ProcessRecord mHeavyWeightProcess = null;
757 * All of the processes we currently have running organized by pid.
758 * The keys are the pid running the application.
760 * <p>NOTE: This object is protected by its own lock, NOT the global
761 * activity manager lock!
763 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
766 * All of the processes that have been forced to be foreground. The key
767 * is the pid of the caller who requested it (we hold a death
770 abstract class ForegroundToken implements IBinder.DeathRecipient {
774 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
777 * List of records for processes that someone had tried to start before the
778 * system was ready. We don't start them at that point, but ensure they
779 * are started by the time booting is complete.
781 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
784 * List of persistent applications that are in the process
787 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
790 * Processes that are being forcibly torn down.
792 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
795 * List of running applications, sorted by recent usage.
796 * The first entry in the list is the least recently used.
798 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
801 * Where in mLruProcesses that the processes hosting activities start.
803 int mLruProcessActivityStart = 0;
806 * Where in mLruProcesses that the processes hosting services start.
807 * This is after (lower index) than mLruProcessesActivityStart.
809 int mLruProcessServiceStart = 0;
812 * List of processes that should gc as soon as things are idle.
814 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
817 * Processes we want to collect PSS data from.
819 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
821 private boolean mBinderTransactionTrackingEnabled = false;
824 * Last time we requested PSS data of all processes.
826 long mLastFullPssTime = SystemClock.uptimeMillis();
829 * If set, the next time we collect PSS data we should do a full collection
830 * with data from native processes and the kernel.
832 boolean mFullPssPending = false;
835 * This is the process holding what we currently consider to be
836 * the "home" activity.
838 ProcessRecord mHomeProcess;
841 * This is the process holding the activity the user last visited that
842 * is in a different process from the one they are currently in.
844 ProcessRecord mPreviousProcess;
847 * The time at which the previous process was last visible.
849 long mPreviousProcessVisibleTime;
852 * Track all uids that have actively running processes.
854 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
857 * This is for verifying the UID report flow.
859 static final boolean VALIDATE_UID_STATES = true;
860 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
863 * Packages that the user has asked to have run in screen size
864 * compatibility mode instead of filling the screen.
866 final CompatModePackages mCompatModePackages;
869 * Set of IntentSenderRecord objects that are currently active.
871 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
875 * Fingerprints (hashCode()) of stack traces that we've
876 * already logged DropBox entries for. Guarded by itself. If
877 * something (rogue user app) forces this over
878 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
880 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
884 * Strict Mode background batched logging state.
886 * The string buffer is guarded by itself, and its lock is also
887 * used to determine if another batched write is already
890 private final StringBuilder mStrictModeBuffer = new StringBuilder();
893 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
896 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
899 * Resolver for broadcast intents to registered receivers.
900 * Holds BroadcastFilter (subclass of IntentFilter).
902 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
905 protected boolean allowFilterResult(
906 BroadcastFilter filter, List<BroadcastFilter> dest) {
907 IBinder target = filter.receiverList.receiver.asBinder();
908 for (int i = dest.size() - 1; i >= 0; i--) {
909 if (dest.get(i).receiverList.receiver.asBinder() == target) {
917 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919 || userId == filter.owningUserId) {
920 return super.newResult(filter, match, userId);
926 protected BroadcastFilter[] newArray(int size) {
927 return new BroadcastFilter[size];
931 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932 return packageName.equals(filter.packageName);
937 * State of all active sticky broadcasts per user. Keys are the action of the
938 * sticky Intent, values are an ArrayList of all broadcasted intents with
939 * that action (which should usually be one). The SparseArray is keyed
940 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941 * for stickies that are sent to all users.
943 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
946 final ActiveServices mServices;
948 final static class Association {
949 final int mSourceUid;
950 final String mSourceProcess;
951 final int mTargetUid;
952 final ComponentName mTargetComponent;
953 final String mTargetProcess;
961 // states of the source process when the bind occurred.
962 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963 long mLastStateUptime;
964 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965 - ActivityManager.MIN_PROCESS_STATE+1];
967 Association(int sourceUid, String sourceProcess, int targetUid,
968 ComponentName targetComponent, String targetProcess) {
969 mSourceUid = sourceUid;
970 mSourceProcess = sourceProcess;
971 mTargetUid = targetUid;
972 mTargetComponent = targetComponent;
973 mTargetProcess = targetProcess;
978 * When service association tracking is enabled, this is all of the associations we
979 * have seen. Mapping is target uid -> target component -> source uid -> source process name
980 * -> association data.
982 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983 mAssociations = new SparseArray<>();
984 boolean mTrackingAssociations;
987 * Backup/restore process management
989 String mBackupAppName = null;
990 BackupRecord mBackupTarget = null;
992 final ProviderMap mProviderMap;
995 * List of content providers who have clients waiting for them. The
996 * application is currently being launched and the provider will be
997 * removed from this list once it is published.
999 final ArrayList<ContentProviderRecord> mLaunchingProviders
1000 = new ArrayList<ContentProviderRecord>();
1003 * File storing persisted {@link #mGrantedUriPermissions}.
1005 private final AtomicFile mGrantFile;
1007 /** XML constants used in {@link #mGrantFile} */
1008 private static final String TAG_URI_GRANTS = "uri-grants";
1009 private static final String TAG_URI_GRANT = "uri-grant";
1010 private static final String ATTR_USER_HANDLE = "userHandle";
1011 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014 private static final String ATTR_TARGET_PKG = "targetPkg";
1015 private static final String ATTR_URI = "uri";
1016 private static final String ATTR_MODE_FLAGS = "modeFlags";
1017 private static final String ATTR_CREATED_TIME = "createdTime";
1018 private static final String ATTR_PREFIX = "prefix";
1021 * Global set of specific {@link Uri} permissions that have been granted.
1022 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023 * to {@link UriPermission#uri} to {@link UriPermission}.
1026 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1029 public static class GrantUri {
1030 public final int sourceUserId;
1031 public final Uri uri;
1032 public boolean prefix;
1034 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035 this.sourceUserId = sourceUserId;
1037 this.prefix = prefix;
1041 public int hashCode() {
1043 hashCode = 31 * hashCode + sourceUserId;
1044 hashCode = 31 * hashCode + uri.hashCode();
1045 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1050 public boolean equals(Object o) {
1051 if (o instanceof GrantUri) {
1052 GrantUri other = (GrantUri) o;
1053 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054 && prefix == other.prefix;
1060 public String toString() {
1061 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062 if (prefix) result += " [prefix]";
1066 public String toSafeString() {
1067 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068 if (prefix) result += " [prefix]";
1072 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074 ContentProvider.getUriWithoutUserId(uri), false);
1078 CoreSettingsObserver mCoreSettingsObserver;
1080 FontScaleSettingObserver mFontScaleSettingObserver;
1082 private final class FontScaleSettingObserver extends ContentObserver {
1083 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1085 public FontScaleSettingObserver() {
1087 ContentResolver resolver = mContext.getContentResolver();
1088 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1092 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093 if (mFontScaleUri.equals(uri)) {
1094 updateFontScaleIfNeeded(userId);
1100 * Thread-local storage used to carry caller permissions over through
1101 * indirect content-provider access.
1103 private class Identity {
1104 public final IBinder token;
1105 public final int pid;
1106 public final int uid;
1108 Identity(IBinder _token, int _pid, int _uid) {
1115 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1118 * All information we have collected about the runtime performance of
1119 * any user id that can impact battery performance.
1121 final BatteryStatsService mBatteryStatsService;
1124 * Information about component usage
1126 UsageStatsManagerInternal mUsageStatsService;
1129 * Access to DeviceIdleController service.
1131 DeviceIdleController.LocalService mLocalDeviceIdleController;
1134 * Information about and control over application operations
1136 final AppOpsService mAppOpsService;
1139 * Current configuration information. HistoryRecord objects are given
1140 * a reference to this object to indicate which configuration they are
1141 * currently running in, so this object must be kept immutable.
1143 Configuration mConfiguration = new Configuration();
1146 * Current sequencing integer of the configuration, for skipping old
1149 int mConfigurationSeq = 0;
1151 boolean mSuppressResizeConfigChanges = false;
1154 * Hardware-reported OpenGLES version.
1156 final int GL_ES_VERSION;
1159 * List of initialization arguments to pass to all processes when binding applications to them.
1160 * For example, references to the commonly used services.
1162 HashMap<String, IBinder> mAppBindArgs;
1163 HashMap<String, IBinder> mIsolatedAppBindArgs;
1166 * Temporary to avoid allocations. Protected by main lock.
1168 final StringBuilder mStringBuilder = new StringBuilder(256);
1171 * Used to control how we initialize the service.
1173 ComponentName mTopComponent;
1174 String mTopAction = Intent.ACTION_MAIN;
1177 volatile boolean mProcessesReady = false;
1178 volatile boolean mSystemReady = false;
1179 volatile boolean mOnBattery = false;
1180 volatile int mFactoryTest;
1182 @GuardedBy("this") boolean mBooting = false;
1183 @GuardedBy("this") boolean mCallFinishBooting = false;
1184 @GuardedBy("this") boolean mBootAnimationComplete = false;
1185 @GuardedBy("this") boolean mLaunchWarningShown = false;
1186 @GuardedBy("this") boolean mCheckedForSetup = false;
1191 * The time at which we will allow normal application switches again,
1192 * after a call to {@link #stopAppSwitches()}.
1194 long mAppSwitchesAllowedTime;
1197 * This is set to true after the first switch after mAppSwitchesAllowedTime
1198 * is set; any switches after that will clear the time.
1200 boolean mDidAppSwitch;
1203 * Last time (in realtime) at which we checked for power usage.
1205 long mLastPowerCheckRealtime;
1208 * Last time (in uptime) at which we checked for power usage.
1210 long mLastPowerCheckUptime;
1213 * Set while we are wanting to sleep, to prevent any
1214 * activities from being started/resumed.
1216 private boolean mSleeping = false;
1219 * The process state used for processes that are running the top activities.
1220 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1222 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1225 * Set while we are running a voice interaction. This overrides
1226 * sleeping while it is active.
1228 private IVoiceInteractionSession mRunningVoice;
1231 * For some direct access we need to power manager.
1233 PowerManagerInternal mLocalPowerManager;
1236 * We want to hold a wake lock while running a voice interaction session, since
1237 * this may happen with the screen off and we need to keep the CPU running to
1238 * be able to continue to interact with the user.
1240 PowerManager.WakeLock mVoiceWakeLock;
1243 * State of external calls telling us if the device is awake or asleep.
1245 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1248 * A list of tokens that cause the top activity to be put to sleep.
1249 * They are used by components that may hide and block interaction with underlying
1252 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1254 static final int LOCK_SCREEN_HIDDEN = 0;
1255 static final int LOCK_SCREEN_LEAVING = 1;
1256 static final int LOCK_SCREEN_SHOWN = 2;
1258 * State of external call telling us if the lock screen is shown.
1260 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1263 * Set if we are shutting down the system, similar to sleeping.
1265 boolean mShuttingDown = false;
1268 * Current sequence id for oom_adj computation traversal.
1273 * Current sequence id for process LRU updating.
1278 * Keep track of the non-cached/empty process we last found, to help
1279 * determine how to distribute cached/empty processes next time.
1281 int mNumNonCachedProcs = 0;
1284 * Keep track of the number of cached hidden procs, to balance oom adj
1285 * distribution between those and empty procs.
1287 int mNumCachedHiddenProcs = 0;
1290 * Keep track of the number of service processes we last found, to
1291 * determine on the next iteration which should be B services.
1293 int mNumServiceProcs = 0;
1294 int mNewNumAServiceProcs = 0;
1295 int mNewNumServiceProcs = 0;
1298 * Allow the current computed overall memory level of the system to go down?
1299 * This is set to false when we are killing processes for reasons other than
1300 * memory management, so that the now smaller process list will not be taken as
1301 * an indication that memory is tighter.
1303 boolean mAllowLowerMemLevel = false;
1306 * The last computed memory level, for holding when we are in a state that
1307 * processes are going away for other reasons.
1309 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1312 * The last total number of process we have, to determine if changes actually look
1313 * like a shrinking number of process due to lower RAM.
1315 int mLastNumProcesses;
1318 * The uptime of the last time we performed idle maintenance.
1320 long mLastIdleTime = SystemClock.uptimeMillis();
1323 * Total time spent with RAM that has been added in the past since the last idle time.
1325 long mLowRamTimeSinceLastIdle = 0;
1328 * If RAM is currently low, when that horrible situation started.
1330 long mLowRamStartTime = 0;
1333 * For reporting to battery stats the current top application.
1335 private String mCurResumedPackage = null;
1336 private int mCurResumedUid = -1;
1339 * For reporting to battery stats the apps currently running foreground
1340 * service. The ProcessMap is package/uid tuples; each of these contain
1341 * an array of the currently foreground processes.
1343 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1344 = new ProcessMap<ArrayList<ProcessRecord>>();
1347 * This is set if we had to do a delayed dexopt of an app before launching
1348 * it, to increase the ANR timeouts in that case.
1353 * Set if the systemServer made a call to enterSafeMode.
1358 * If true, we are running under a test environment so will sample PSS from processes
1359 * much more rapidly to try to collect better data when the tests are rapidly
1360 * running through apps.
1362 boolean mTestPssMode = false;
1364 String mDebugApp = null;
1365 boolean mWaitForDebugger = false;
1366 boolean mDebugTransient = false;
1367 String mOrigDebugApp = null;
1368 boolean mOrigWaitForDebugger = false;
1369 boolean mAlwaysFinishActivities = false;
1370 boolean mLenientBackgroundCheck = false;
1371 boolean mForceResizableActivities;
1372 boolean mSupportsMultiWindow;
1373 boolean mSupportsFreeformWindowManagement;
1374 boolean mSupportsPictureInPicture;
1375 boolean mSupportsLeanbackOnly;
1376 Rect mDefaultPinnedStackBounds;
1377 IActivityController mController = null;
1378 boolean mControllerIsAMonkey = false;
1379 String mProfileApp = null;
1380 ProcessRecord mProfileProc = null;
1381 String mProfileFile;
1382 ParcelFileDescriptor mProfileFd;
1383 int mSamplingInterval = 0;
1384 boolean mAutoStopProfiler = false;
1385 int mProfileType = 0;
1386 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1387 String mMemWatchDumpProcName;
1388 String mMemWatchDumpFile;
1389 int mMemWatchDumpPid;
1390 int mMemWatchDumpUid;
1391 String mTrackAllocationApp = null;
1392 String mNativeDebuggingApp = null;
1394 final long[] mTmpLong = new long[2];
1396 static final class ProcessChangeItem {
1397 static final int CHANGE_ACTIVITIES = 1<<0;
1398 static final int CHANGE_PROCESS_STATE = 1<<1;
1403 boolean foregroundActivities;
1406 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1407 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1409 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1410 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1412 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1413 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1415 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1416 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1419 * Runtime CPU use collection thread. This object's lock is used to
1420 * perform synchronization with the thread (notifying it to run).
1422 final Thread mProcessCpuThread;
1425 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1426 * Must acquire this object's lock when accessing it.
1427 * NOTE: this lock will be held while doing long operations (trawling
1428 * through all processes in /proc), so it should never be acquired by
1429 * any critical paths such as when holding the main activity manager lock.
1431 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1432 MONITOR_THREAD_CPU_USAGE);
1433 final AtomicLong mLastCpuTime = new AtomicLong(0);
1434 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1436 long mLastWriteTime = 0;
1439 * Used to retain an update lock when the foreground activity is in
1442 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1445 * Set to true after the system has finished booting.
1447 boolean mBooted = false;
1449 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1450 int mProcessLimitOverride = -1;
1452 WindowManagerService mWindowManager;
1453 final ActivityThread mSystemThread;
1455 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1456 final ProcessRecord mApp;
1458 final IApplicationThread mAppThread;
1460 AppDeathRecipient(ProcessRecord app, int pid,
1461 IApplicationThread thread) {
1462 if (DEBUG_ALL) Slog.v(
1463 TAG, "New death recipient " + this
1464 + " for thread " + thread.asBinder());
1467 mAppThread = thread;
1471 public void binderDied() {
1472 if (DEBUG_ALL) Slog.v(
1473 TAG, "Death received in " + this
1474 + " for thread " + mAppThread.asBinder());
1475 synchronized(ActivityManagerService.this) {
1476 appDiedLocked(mApp, mPid, mAppThread, true);
1481 static final int SHOW_ERROR_UI_MSG = 1;
1482 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1483 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1484 static final int UPDATE_CONFIGURATION_MSG = 4;
1485 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1486 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1487 static final int SERVICE_TIMEOUT_MSG = 12;
1488 static final int UPDATE_TIME_ZONE = 13;
1489 static final int SHOW_UID_ERROR_UI_MSG = 14;
1490 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1491 static final int PROC_START_TIMEOUT_MSG = 20;
1492 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1493 static final int KILL_APPLICATION_MSG = 22;
1494 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1495 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1496 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1497 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1498 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1499 static final int CLEAR_DNS_CACHE_MSG = 28;
1500 static final int UPDATE_HTTP_PROXY_MSG = 29;
1501 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1502 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1503 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1504 static final int REPORT_MEM_USAGE_MSG = 33;
1505 static final int REPORT_USER_SWITCH_MSG = 34;
1506 static final int CONTINUE_USER_SWITCH_MSG = 35;
1507 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1508 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1509 static final int PERSIST_URI_GRANTS_MSG = 38;
1510 static final int REQUEST_ALL_PSS_MSG = 39;
1511 static final int START_PROFILES_MSG = 40;
1512 static final int UPDATE_TIME = 41;
1513 static final int SYSTEM_USER_START_MSG = 42;
1514 static final int SYSTEM_USER_CURRENT_MSG = 43;
1515 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1516 static final int FINISH_BOOTING_MSG = 45;
1517 static final int START_USER_SWITCH_UI_MSG = 46;
1518 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1519 static final int DISMISS_DIALOG_UI_MSG = 48;
1520 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1521 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1522 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1523 static final int DELETE_DUMPHEAP_MSG = 52;
1524 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1525 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1526 static final int REPORT_TIME_TRACKER_MSG = 55;
1527 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1528 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1529 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1530 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1531 static final int IDLE_UIDS_MSG = 60;
1532 static final int SYSTEM_USER_UNLOCK_MSG = 61;
1533 static final int LOG_STACK_STATE = 62;
1534 static final int VR_MODE_CHANGE_MSG = 63;
1535 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1536 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1537 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1538 static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1539 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1540 static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1541 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1543 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1544 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1545 static final int FIRST_COMPAT_MODE_MSG = 300;
1546 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1548 static ServiceThread sKillThread = null;
1549 static KillHandler sKillHandler = null;
1551 CompatModeDialog mCompatModeDialog;
1552 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1553 long mLastMemUsageReportTime = 0;
1556 * Flag whether the current user is a "monkey", i.e. whether
1557 * the UI is driven by a UI automation tool.
1559 private boolean mUserIsMonkey;
1561 /** Flag whether the device has a Recents UI */
1562 boolean mHasRecents;
1564 /** The dimensions of the thumbnails in the Recents UI. */
1565 int mThumbnailWidth;
1566 int mThumbnailHeight;
1567 float mFullscreenThumbnailScale;
1569 final ServiceThread mHandlerThread;
1570 final MainHandler mHandler;
1571 final UiHandler mUiHandler;
1573 PackageManagerInternal mPackageManagerInt;
1575 // VoiceInteraction session ID that changes for each new request except when
1576 // being called for multiwindow assist in a single session.
1577 private int mViSessionId = 1000;
1579 final boolean mPermissionReviewRequired;
1581 final class KillHandler extends Handler {
1582 static final int KILL_PROCESS_GROUP_MSG = 4000;
1584 public KillHandler(Looper looper) {
1585 super(looper, null, true);
1589 public void handleMessage(Message msg) {
1591 case KILL_PROCESS_GROUP_MSG:
1593 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1594 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1595 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1600 super.handleMessage(msg);
1605 final class UiHandler extends Handler {
1606 public UiHandler() {
1607 super(com.android.server.UiThread.get().getLooper(), null, true);
1611 public void handleMessage(Message msg) {
1613 case SHOW_ERROR_UI_MSG: {
1614 mAppErrors.handleShowAppErrorUi(msg);
1615 ensureBootCompleted();
1617 case SHOW_NOT_RESPONDING_UI_MSG: {
1618 mAppErrors.handleShowAnrUi(msg);
1619 ensureBootCompleted();
1621 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1622 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1623 synchronized (ActivityManagerService.this) {
1624 ProcessRecord proc = (ProcessRecord) data.get("app");
1626 Slog.e(TAG, "App not found when showing strict mode dialog.");
1629 if (proc.crashDialog != null) {
1630 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1633 AppErrorResult res = (AppErrorResult) data.get("result");
1634 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1635 Dialog d = new StrictModeViolationDialog(mContext,
1636 ActivityManagerService.this, res, proc);
1638 proc.crashDialog = d;
1640 // The device is asleep, so just pretend that the user
1641 // saw a crash dialog and hit "force quit".
1645 ensureBootCompleted();
1647 case SHOW_FACTORY_ERROR_UI_MSG: {
1648 Dialog d = new FactoryErrorDialog(
1649 mContext, msg.getData().getCharSequence("msg"));
1651 ensureBootCompleted();
1653 case WAIT_FOR_DEBUGGER_UI_MSG: {
1654 synchronized (ActivityManagerService.this) {
1655 ProcessRecord app = (ProcessRecord)msg.obj;
1656 if (msg.arg1 != 0) {
1657 if (!app.waitedForDebugger) {
1658 Dialog d = new AppWaitingForDebuggerDialog(
1659 ActivityManagerService.this,
1662 app.waitedForDebugger = true;
1666 if (app.waitDialog != null) {
1667 app.waitDialog.dismiss();
1668 app.waitDialog = null;
1673 case SHOW_UID_ERROR_UI_MSG: {
1675 AlertDialog d = new BaseErrorDialog(mContext);
1676 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1677 d.setCancelable(false);
1678 d.setTitle(mContext.getText(R.string.android_system_label));
1679 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1680 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1681 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1685 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1687 AlertDialog d = new BaseErrorDialog(mContext);
1688 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1689 d.setCancelable(false);
1690 d.setTitle(mContext.getText(R.string.android_system_label));
1691 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1692 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1693 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1697 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1698 synchronized (ActivityManagerService.this) {
1699 ActivityRecord ar = (ActivityRecord) msg.obj;
1700 if (mCompatModeDialog != null) {
1701 if (mCompatModeDialog.mAppInfo.packageName.equals(
1702 ar.info.applicationInfo.packageName)) {
1705 mCompatModeDialog.dismiss();
1706 mCompatModeDialog = null;
1708 if (ar != null && false) {
1709 if (mCompatModePackages.getPackageAskCompatModeLocked(
1711 int mode = mCompatModePackages.computeCompatModeLocked(
1712 ar.info.applicationInfo);
1713 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1714 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1715 mCompatModeDialog = new CompatModeDialog(
1716 ActivityManagerService.this, mContext,
1717 ar.info.applicationInfo);
1718 mCompatModeDialog.show();
1725 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1726 synchronized (ActivityManagerService.this) {
1727 final ActivityRecord ar = (ActivityRecord) msg.obj;
1728 if (mUnsupportedDisplaySizeDialog != null) {
1729 mUnsupportedDisplaySizeDialog.dismiss();
1730 mUnsupportedDisplaySizeDialog = null;
1732 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1734 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1735 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1736 mUnsupportedDisplaySizeDialog.show();
1741 case START_USER_SWITCH_UI_MSG: {
1742 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1745 case DISMISS_DIALOG_UI_MSG: {
1746 final Dialog d = (Dialog) msg.obj;
1750 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1751 dispatchProcessesChanged();
1754 case DISPATCH_PROCESS_DIED_UI_MSG: {
1755 final int pid = msg.arg1;
1756 final int uid = msg.arg2;
1757 dispatchProcessDied(pid, uid);
1760 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1761 dispatchUidsChanged();
1767 final class MainHandler extends Handler {
1768 public MainHandler(Looper looper) {
1769 super(looper, null, true);
1773 public void handleMessage(Message msg) {
1775 case UPDATE_CONFIGURATION_MSG: {
1776 final ContentResolver resolver = mContext.getContentResolver();
1777 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1780 case GC_BACKGROUND_PROCESSES_MSG: {
1781 synchronized (ActivityManagerService.this) {
1782 performAppGcsIfAppropriateLocked();
1785 case SERVICE_TIMEOUT_MSG: {
1788 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1790 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1793 mServices.serviceTimeout((ProcessRecord)msg.obj);
1795 case UPDATE_TIME_ZONE: {
1796 synchronized (ActivityManagerService.this) {
1797 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1798 ProcessRecord r = mLruProcesses.get(i);
1799 if (r.thread != null) {
1801 r.thread.updateTimeZone();
1802 } catch (RemoteException ex) {
1803 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1809 case CLEAR_DNS_CACHE_MSG: {
1810 synchronized (ActivityManagerService.this) {
1811 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1812 ProcessRecord r = mLruProcesses.get(i);
1813 if (r.thread != null) {
1815 r.thread.clearDnsCache();
1816 } catch (RemoteException ex) {
1817 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1823 case UPDATE_HTTP_PROXY_MSG: {
1824 ProxyInfo proxy = (ProxyInfo)msg.obj;
1827 String exclList = "";
1828 Uri pacFileUrl = Uri.EMPTY;
1829 if (proxy != null) {
1830 host = proxy.getHost();
1831 port = Integer.toString(proxy.getPort());
1832 exclList = proxy.getExclusionListAsString();
1833 pacFileUrl = proxy.getPacFileUrl();
1835 synchronized (ActivityManagerService.this) {
1836 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1837 ProcessRecord r = mLruProcesses.get(i);
1838 if (r.thread != null) {
1840 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1841 } catch (RemoteException ex) {
1842 Slog.w(TAG, "Failed to update http proxy for: " +
1843 r.info.processName);
1849 case PROC_START_TIMEOUT_MSG: {
1852 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1854 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1857 ProcessRecord app = (ProcessRecord)msg.obj;
1858 synchronized (ActivityManagerService.this) {
1859 processStartTimedOutLocked(app);
1862 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1863 ProcessRecord app = (ProcessRecord)msg.obj;
1864 synchronized (ActivityManagerService.this) {
1865 processContentProviderPublishTimedOutLocked(app);
1868 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1869 synchronized (ActivityManagerService.this) {
1870 mActivityStarter.doPendingActivityLaunchesLocked(true);
1873 case KILL_APPLICATION_MSG: {
1874 synchronized (ActivityManagerService.this) {
1875 final int appId = msg.arg1;
1876 final int userId = msg.arg2;
1877 Bundle bundle = (Bundle)msg.obj;
1878 String pkg = bundle.getString("pkg");
1879 String reason = bundle.getString("reason");
1880 forceStopPackageLocked(pkg, appId, false, false, true, false,
1881 false, userId, reason);
1884 case FINALIZE_PENDING_INTENT_MSG: {
1885 ((PendingIntentRecord)msg.obj).completeFinalize();
1887 case POST_HEAVY_NOTIFICATION_MSG: {
1888 INotificationManager inm = NotificationManager.getService();
1893 ActivityRecord root = (ActivityRecord)msg.obj;
1894 ProcessRecord process = root.app;
1895 if (process == null) {
1900 Context context = mContext.createPackageContext(process.info.packageName, 0);
1901 String text = mContext.getString(R.string.heavy_weight_notification,
1902 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1903 Notification notification = new Notification.Builder(context)
1904 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1908 .setColor(mContext.getColor(
1909 com.android.internal.R.color.system_notification_accent_color))
1910 .setContentTitle(text)
1912 mContext.getText(R.string.heavy_weight_notification_detail))
1913 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1914 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1915 new UserHandle(root.userId)))
1918 int[] outId = new int[1];
1919 inm.enqueueNotificationWithTag("android", "android", null,
1920 R.string.heavy_weight_notification,
1921 notification, outId, root.userId);
1922 } catch (RuntimeException e) {
1923 Slog.w(ActivityManagerService.TAG,
1924 "Error showing notification for heavy-weight app", e);
1925 } catch (RemoteException e) {
1927 } catch (NameNotFoundException e) {
1928 Slog.w(TAG, "Unable to create context for heavy notification", e);
1931 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1932 INotificationManager inm = NotificationManager.getService();
1937 inm.cancelNotificationWithTag("android", null,
1938 R.string.heavy_weight_notification, msg.arg1);
1939 } catch (RuntimeException e) {
1940 Slog.w(ActivityManagerService.TAG,
1941 "Error canceling notification for service", e);
1942 } catch (RemoteException e) {
1945 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1946 synchronized (ActivityManagerService.this) {
1947 checkExcessivePowerUsageLocked(true);
1948 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1949 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1950 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1953 case REPORT_MEM_USAGE_MSG: {
1954 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1955 Thread thread = new Thread() {
1956 @Override public void run() {
1957 reportMemUsage(memInfos);
1963 case REPORT_USER_SWITCH_MSG: {
1964 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1967 case CONTINUE_USER_SWITCH_MSG: {
1968 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1971 case USER_SWITCH_TIMEOUT_MSG: {
1972 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1975 case IMMERSIVE_MODE_LOCK_MSG: {
1976 final boolean nextState = (msg.arg1 != 0);
1977 if (mUpdateLock.isHeld() != nextState) {
1978 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1979 "Applying new update lock state '" + nextState
1980 + "' for " + (ActivityRecord)msg.obj);
1982 mUpdateLock.acquire();
1984 mUpdateLock.release();
1989 case PERSIST_URI_GRANTS_MSG: {
1990 writeGrantedUriPermissions();
1993 case REQUEST_ALL_PSS_MSG: {
1994 synchronized (ActivityManagerService.this) {
1995 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1999 case START_PROFILES_MSG: {
2000 synchronized (ActivityManagerService.this) {
2001 mUserController.startProfilesLocked();
2006 synchronized (ActivityManagerService.this) {
2007 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2008 ProcessRecord r = mLruProcesses.get(i);
2009 if (r.thread != null) {
2011 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2012 } catch (RemoteException ex) {
2013 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2020 case SYSTEM_USER_START_MSG: {
2021 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2022 Integer.toString(msg.arg1), msg.arg1);
2023 mSystemServiceManager.startUser(msg.arg1);
2026 case SYSTEM_USER_UNLOCK_MSG: {
2027 final int userId = msg.arg1;
2028 mSystemServiceManager.unlockUser(userId);
2029 synchronized (ActivityManagerService.this) {
2030 mRecentTasks.loadUserRecentsLocked(userId);
2032 if (userId == UserHandle.USER_SYSTEM) {
2033 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2035 installEncryptionUnawareProviders(userId);
2036 mUserController.finishUserUnlocked((UserState) msg.obj);
2039 case SYSTEM_USER_CURRENT_MSG: {
2040 mBatteryStatsService.noteEvent(
2041 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2042 Integer.toString(msg.arg2), msg.arg2);
2043 mBatteryStatsService.noteEvent(
2044 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2045 Integer.toString(msg.arg1), msg.arg1);
2046 mSystemServiceManager.switchUser(msg.arg1);
2049 case ENTER_ANIMATION_COMPLETE_MSG: {
2050 synchronized (ActivityManagerService.this) {
2051 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2052 if (r != null && r.app != null && r.app.thread != null) {
2054 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2055 } catch (RemoteException e) {
2061 case FINISH_BOOTING_MSG: {
2062 if (msg.arg1 != 0) {
2063 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2065 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2067 if (msg.arg2 != 0) {
2068 enableScreenAfterBoot();
2072 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2074 Locale l = (Locale) msg.obj;
2075 IBinder service = ServiceManager.getService("mount");
2076 IMountService mountService = IMountService.Stub.asInterface(service);
2077 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2078 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2079 } catch (RemoteException e) {
2080 Log.e(TAG, "Error storing locale for decryption UI", e);
2084 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2085 synchronized (ActivityManagerService.this) {
2086 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2088 // Make a one-way callback to the listener
2089 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2090 } catch (RemoteException e){
2091 // Handled by the RemoteCallbackList
2094 mTaskStackListeners.finishBroadcast();
2098 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2099 synchronized (ActivityManagerService.this) {
2100 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2102 // Make a one-way callback to the listener
2103 mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2104 } catch (RemoteException e){
2105 // Handled by the RemoteCallbackList
2108 mTaskStackListeners.finishBroadcast();
2112 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2113 synchronized (ActivityManagerService.this) {
2114 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2116 // Make a one-way callback to the listener
2117 mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2118 } catch (RemoteException e){
2119 // Handled by the RemoteCallbackList
2122 mTaskStackListeners.finishBroadcast();
2126 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2127 synchronized (ActivityManagerService.this) {
2128 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2130 // Make a one-way callback to the listener
2131 mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2132 } catch (RemoteException e){
2133 // Handled by the RemoteCallbackList
2136 mTaskStackListeners.finishBroadcast();
2140 case NOTIFY_FORCED_RESIZABLE_MSG: {
2141 synchronized (ActivityManagerService.this) {
2142 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2144 // Make a one-way callback to the listener
2145 mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2146 (String) msg.obj, msg.arg1);
2147 } catch (RemoteException e){
2148 // Handled by the RemoteCallbackList
2151 mTaskStackListeners.finishBroadcast();
2155 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2156 synchronized (ActivityManagerService.this) {
2157 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2159 // Make a one-way callback to the listener
2160 mTaskStackListeners.getBroadcastItem(i)
2161 .onActivityDismissingDockedStack();
2162 } catch (RemoteException e){
2163 // Handled by the RemoteCallbackList
2166 mTaskStackListeners.finishBroadcast();
2170 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2171 final int uid = msg.arg1;
2172 final byte[] firstPacket = (byte[]) msg.obj;
2174 synchronized (mPidsSelfLocked) {
2175 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2176 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2179 p.thread.notifyCleartextNetwork(firstPacket);
2180 } catch (RemoteException ignored) {
2187 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2188 final String procName;
2190 final long memLimit;
2191 final String reportPackage;
2192 synchronized (ActivityManagerService.this) {
2193 procName = mMemWatchDumpProcName;
2194 uid = mMemWatchDumpUid;
2195 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2197 val = mMemWatchProcesses.get(procName, 0);
2200 memLimit = val.first;
2201 reportPackage = val.second;
2204 reportPackage = null;
2207 if (procName == null) {
2211 if (DEBUG_PSS) Slog.d(TAG_PSS,
2212 "Showing dump heap notification from " + procName + "/" + uid);
2214 INotificationManager inm = NotificationManager.getService();
2219 String text = mContext.getString(R.string.dump_heap_notification, procName);
2222 Intent deleteIntent = new Intent();
2223 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2224 Intent intent = new Intent();
2225 intent.setClassName("android", DumpHeapActivity.class.getName());
2226 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2227 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2228 if (reportPackage != null) {
2229 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2231 int userId = UserHandle.getUserId(uid);
2232 Notification notification = new Notification.Builder(mContext)
2233 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2236 .setAutoCancel(true)
2238 .setColor(mContext.getColor(
2239 com.android.internal.R.color.system_notification_accent_color))
2240 .setContentTitle(text)
2242 mContext.getText(R.string.dump_heap_notification_detail))
2243 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2244 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2245 new UserHandle(userId)))
2246 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2247 deleteIntent, 0, UserHandle.SYSTEM))
2251 int[] outId = new int[1];
2252 inm.enqueueNotificationWithTag("android", "android", null,
2253 R.string.dump_heap_notification,
2254 notification, outId, userId);
2255 } catch (RuntimeException e) {
2256 Slog.w(ActivityManagerService.TAG,
2257 "Error showing notification for dump heap", e);
2258 } catch (RemoteException e) {
2261 case DELETE_DUMPHEAP_MSG: {
2262 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2263 DumpHeapActivity.JAVA_URI,
2264 Intent.FLAG_GRANT_READ_URI_PERMISSION
2265 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2266 UserHandle.myUserId());
2267 synchronized (ActivityManagerService.this) {
2268 mMemWatchDumpFile = null;
2269 mMemWatchDumpProcName = null;
2270 mMemWatchDumpPid = -1;
2271 mMemWatchDumpUid = -1;
2274 case FOREGROUND_PROFILE_CHANGED_MSG: {
2275 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2277 case REPORT_TIME_TRACKER_MSG: {
2278 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2279 tracker.deliverResult(mContext);
2281 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2282 mUserController.dispatchUserSwitchComplete(msg.arg1);
2284 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2285 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2287 connection.shutdown();
2288 } catch (RemoteException e) {
2289 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2291 // Only a UiAutomation can set this flag and now that
2292 // it is finished we make sure it is reset to its default.
2293 mUserIsMonkey = false;
2295 case APP_BOOST_DEACTIVATE_MSG: {
2296 synchronized(ActivityManagerService.this) {
2298 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2299 nativeMigrateFromBoost();
2301 mBoostStartTime = 0;
2303 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2304 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2309 case IDLE_UIDS_MSG: {
2312 case LOG_STACK_STATE: {
2313 synchronized (ActivityManagerService.this) {
2314 mStackSupervisor.logStackState();
2317 case VR_MODE_CHANGE_MSG: {
2318 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2319 if (vrService == null) {
2322 final ActivityRecord r = (ActivityRecord) msg.obj;
2324 ComponentName requestedPackage;
2325 ComponentName callingPackage;
2327 synchronized (ActivityManagerService.this) {
2328 vrMode = r.requestedVrComponent != null;
2329 requestedPackage = r.requestedVrComponent;
2331 callingPackage = r.info.getComponentName();
2332 if (mInVrMode != vrMode) {
2334 mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2335 if (r.app != null) {
2336 ProcessRecord proc = r.app;
2337 if (proc.vrThreadTid > 0) {
2338 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2340 if (mInVrMode == true) {
2341 Process.setThreadScheduler(proc.vrThreadTid,
2342 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2344 Process.setThreadScheduler(proc.vrThreadTid,
2345 Process.SCHED_OTHER, 0);
2347 } catch (IllegalArgumentException e) {
2348 Slog.w(TAG, "Failed to set scheduling policy, thread does"
2349 + " not exist:\n" + e);
2356 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2358 case VR_MODE_APPLY_IF_NEEDED_MSG: {
2359 final ActivityRecord r = (ActivityRecord) msg.obj;
2360 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2362 applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2363 r.info.getComponentName(), false);
2370 static final int COLLECT_PSS_BG_MSG = 1;
2372 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2374 public void handleMessage(Message msg) {
2376 case COLLECT_PSS_BG_MSG: {
2377 long start = SystemClock.uptimeMillis();
2378 MemInfoReader memInfo = null;
2379 synchronized (ActivityManagerService.this) {
2380 if (mFullPssPending) {
2381 mFullPssPending = false;
2382 memInfo = new MemInfoReader();
2385 if (memInfo != null) {
2386 updateCpuStatsNow();
2387 long nativeTotalPss = 0;
2388 final List<ProcessCpuTracker.Stats> stats;
2389 synchronized (mProcessCpuTracker) {
2390 stats = mProcessCpuTracker.getStats( (st)-> {
2391 return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2394 final int N = stats.size();
2395 for (int j = 0; j < N; j++) {
2396 synchronized (mPidsSelfLocked) {
2397 if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2398 // This is one of our own processes; skip it.
2402 nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2404 memInfo.readMemInfo();
2405 synchronized (ActivityManagerService.this) {
2406 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2407 + (SystemClock.uptimeMillis()-start) + "ms");
2408 final long cachedKb = memInfo.getCachedSizeKb();
2409 final long freeKb = memInfo.getFreeSizeKb();
2410 final long zramKb = memInfo.getZramTotalSizeKb();
2411 final long kernelKb = memInfo.getKernelUsedSizeKb();
2412 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2413 kernelKb*1024, nativeTotalPss*1024);
2414 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2420 long[] tmp = new long[2];
2426 synchronized (ActivityManagerService.this) {
2427 if (mPendingPssProcesses.size() <= 0) {
2428 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2429 "Collected PSS of " + num + " processes in "
2430 + (SystemClock.uptimeMillis() - start) + "ms");
2431 mPendingPssProcesses.clear();
2434 proc = mPendingPssProcesses.remove(0);
2435 procState = proc.pssProcState;
2436 lastPssTime = proc.lastPssTime;
2437 if (proc.thread != null && procState == proc.setProcState
2438 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2439 < SystemClock.uptimeMillis()) {
2447 long pss = Debug.getPss(pid, tmp, null);
2448 synchronized (ActivityManagerService.this) {
2449 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2450 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2452 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2453 SystemClock.uptimeMillis());
2463 public void setSystemProcess() {
2465 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2466 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2467 ServiceManager.addService("meminfo", new MemBinder(this));
2468 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2469 ServiceManager.addService("dbinfo", new DbBinder(this));
2470 if (MONITOR_CPU_USAGE) {
2471 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2473 ServiceManager.addService("permission", new PermissionController(this));
2474 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2476 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2477 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2478 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2480 synchronized (this) {
2481 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2482 app.persistent = true;
2484 app.maxAdj = ProcessList.SYSTEM_ADJ;
2485 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2486 synchronized (mPidsSelfLocked) {
2487 mPidsSelfLocked.put(app.pid, app);
2489 updateLruProcessLocked(app, false, null);
2490 updateOomAdjLocked();
2492 } catch (PackageManager.NameNotFoundException e) {
2493 throw new RuntimeException(
2494 "Unable to find android system package", e);
2498 public void setWindowManager(WindowManagerService wm) {
2499 mWindowManager = wm;
2500 mStackSupervisor.setWindowManager(wm);
2501 mActivityStarter.setWindowManager(wm);
2504 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2505 mUsageStatsService = usageStatsManager;
2508 public void startObservingNativeCrashes() {
2509 final NativeCrashListener ncl = new NativeCrashListener(this);
2513 public IAppOpsService getAppOpsService() {
2514 return mAppOpsService;
2517 static class MemBinder extends Binder {
2518 ActivityManagerService mActivityManagerService;
2519 MemBinder(ActivityManagerService activityManagerService) {
2520 mActivityManagerService = activityManagerService;
2524 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2525 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2526 != PackageManager.PERMISSION_GRANTED) {
2527 pw.println("Permission Denial: can't dump meminfo from from pid="
2528 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2529 + " without permission " + android.Manifest.permission.DUMP);
2533 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2537 static class GraphicsBinder extends Binder {
2538 ActivityManagerService mActivityManagerService;
2539 GraphicsBinder(ActivityManagerService activityManagerService) {
2540 mActivityManagerService = activityManagerService;
2544 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2545 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2546 != PackageManager.PERMISSION_GRANTED) {
2547 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2548 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2549 + " without permission " + android.Manifest.permission.DUMP);
2553 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2557 static class DbBinder extends Binder {
2558 ActivityManagerService mActivityManagerService;
2559 DbBinder(ActivityManagerService activityManagerService) {
2560 mActivityManagerService = activityManagerService;
2564 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2565 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2566 != PackageManager.PERMISSION_GRANTED) {
2567 pw.println("Permission Denial: can't dump dbinfo from from pid="
2568 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2569 + " without permission " + android.Manifest.permission.DUMP);
2573 mActivityManagerService.dumpDbInfo(fd, pw, args);
2577 static class CpuBinder extends Binder {
2578 ActivityManagerService mActivityManagerService;
2579 CpuBinder(ActivityManagerService activityManagerService) {
2580 mActivityManagerService = activityManagerService;
2584 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2585 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2586 != PackageManager.PERMISSION_GRANTED) {
2587 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2588 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2589 + " without permission " + android.Manifest.permission.DUMP);
2593 synchronized (mActivityManagerService.mProcessCpuTracker) {
2594 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2595 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2596 SystemClock.uptimeMillis()));
2601 public static final class Lifecycle extends SystemService {
2602 private final ActivityManagerService mService;
2604 public Lifecycle(Context context) {
2606 mService = new ActivityManagerService(context);
2610 public void onStart() {
2614 public ActivityManagerService getService() {
2619 // Note: This method is invoked on the main thread but may need to attach various
2620 // handlers to other threads. So take care to be explicit about the looper.
2621 public ActivityManagerService(Context systemContext) {
2622 mContext = systemContext;
2623 mFactoryTest = FactoryTest.getMode();
2624 mSystemThread = ActivityThread.currentActivityThread();
2626 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2628 mPermissionReviewRequired = mContext.getResources().getBoolean(
2629 com.android.internal.R.bool.config_permissionReviewRequired);
2631 mHandlerThread = new ServiceThread(TAG,
2632 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2633 mHandlerThread.start();
2634 mHandler = new MainHandler(mHandlerThread.getLooper());
2635 mUiHandler = new UiHandler();
2637 /* static; one-time init here */
2638 if (sKillHandler == null) {
2639 sKillThread = new ServiceThread(TAG + ":kill",
2640 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2641 sKillThread.start();
2642 sKillHandler = new KillHandler(sKillThread.getLooper());
2645 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2646 "foreground", BROADCAST_FG_TIMEOUT, false);
2647 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2648 "background", BROADCAST_BG_TIMEOUT, true);
2649 mBroadcastQueues[0] = mFgBroadcastQueue;
2650 mBroadcastQueues[1] = mBgBroadcastQueue;
2652 mServices = new ActiveServices(this);
2653 mProviderMap = new ProviderMap(this);
2654 mAppErrors = new AppErrors(mContext, this);
2656 // TODO: Move creation of battery stats service outside of activity manager service.
2657 File dataDir = Environment.getDataDirectory();
2658 File systemDir = new File(dataDir, "system");
2660 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2661 mBatteryStatsService.getActiveStatistics().readLocked();
2662 mBatteryStatsService.scheduleWriteToDisk();
2663 mOnBattery = DEBUG_POWER ? true
2664 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2665 mBatteryStatsService.getActiveStatistics().setCallback(this);
2667 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2669 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2670 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2671 new IAppOpsCallback.Stub() {
2672 @Override public void opChanged(int op, int uid, String packageName) {
2673 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2674 if (mAppOpsService.checkOperation(op, uid, packageName)
2675 != AppOpsManager.MODE_ALLOWED) {
2676 runInBackgroundDisabled(uid);
2682 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2684 mUserController = new UserController(this);
2686 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2687 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2689 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2690 mUseFifoUiScheduling = true;
2693 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2695 mConfiguration.setToDefaults();
2696 mConfiguration.setLocales(LocaleList.getDefault());
2698 mConfigurationSeq = mConfiguration.seq = 1;
2699 mProcessCpuTracker.init();
2701 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2702 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2703 mStackSupervisor = new ActivityStackSupervisor(this);
2704 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2705 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2707 mProcessCpuThread = new Thread("CpuTracker") {
2713 synchronized(this) {
2714 final long now = SystemClock.uptimeMillis();
2715 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2716 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2717 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2718 // + ", write delay=" + nextWriteDelay);
2719 if (nextWriteDelay < nextCpuDelay) {
2720 nextCpuDelay = nextWriteDelay;
2722 if (nextCpuDelay > 0) {
2723 mProcessCpuMutexFree.set(true);
2724 this.wait(nextCpuDelay);
2727 } catch (InterruptedException e) {
2729 updateCpuStatsNow();
2730 } catch (Exception e) {
2731 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2737 Watchdog.getInstance().addMonitor(this);
2738 Watchdog.getInstance().addThread(mHandler);
2741 public void setSystemServiceManager(SystemServiceManager mgr) {
2742 mSystemServiceManager = mgr;
2745 public void setInstaller(Installer installer) {
2746 mInstaller = installer;
2749 private void start() {
2750 Process.removeAllProcessGroups();
2751 mProcessCpuThread.start();
2753 mBatteryStatsService.publish(mContext);
2754 mAppOpsService.publish(mContext);
2755 Slog.d("AppOps", "AppOpsService published");
2756 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2759 void onUserStoppedLocked(int userId) {
2760 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2763 public void initPowerManagement() {
2764 mStackSupervisor.initPowerManagement();
2765 mBatteryStatsService.initPowerManagement();
2766 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2767 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2768 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2769 mVoiceWakeLock.setReferenceCounted(false);
2773 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2774 throws RemoteException {
2775 if (code == SYSPROPS_TRANSACTION) {
2776 // We need to tell all apps about the system property change.
2777 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2778 synchronized(this) {
2779 final int NP = mProcessNames.getMap().size();
2780 for (int ip=0; ip<NP; ip++) {
2781 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2782 final int NA = apps.size();
2783 for (int ia=0; ia<NA; ia++) {
2784 ProcessRecord app = apps.valueAt(ia);
2785 if (app.thread != null) {
2786 procs.add(app.thread.asBinder());
2792 int N = procs.size();
2793 for (int i=0; i<N; i++) {
2794 Parcel data2 = Parcel.obtain();
2796 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2797 } catch (RemoteException e) {
2803 return super.onTransact(code, data, reply, flags);
2804 } catch (RuntimeException e) {
2805 // The activity manager only throws security exceptions, so let's
2807 if (!(e instanceof SecurityException)) {
2808 Slog.wtf(TAG, "Activity Manager Crash", e);
2814 void updateCpuStats() {
2815 final long now = SystemClock.uptimeMillis();
2816 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2819 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2820 synchronized (mProcessCpuThread) {
2821 mProcessCpuThread.notify();
2826 void updateCpuStatsNow() {
2827 synchronized (mProcessCpuTracker) {
2828 mProcessCpuMutexFree.set(false);
2829 final long now = SystemClock.uptimeMillis();
2830 boolean haveNewCpuStats = false;
2832 if (MONITOR_CPU_USAGE &&
2833 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2834 mLastCpuTime.set(now);
2835 mProcessCpuTracker.update();
2836 if (mProcessCpuTracker.hasGoodLastStats()) {
2837 haveNewCpuStats = true;
2838 //Slog.i(TAG, mProcessCpu.printCurrentState());
2839 //Slog.i(TAG, "Total CPU usage: "
2840 // + mProcessCpu.getTotalCpuPercent() + "%");
2842 // Slog the cpu usage if the property is set.
2843 if ("true".equals(SystemProperties.get("events.cpu"))) {
2844 int user = mProcessCpuTracker.getLastUserTime();
2845 int system = mProcessCpuTracker.getLastSystemTime();
2846 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2847 int irq = mProcessCpuTracker.getLastIrqTime();
2848 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2849 int idle = mProcessCpuTracker.getLastIdleTime();
2851 int total = user + system + iowait + irq + softIrq + idle;
2852 if (total == 0) total = 1;
2854 EventLog.writeEvent(EventLogTags.CPU,
2855 ((user+system+iowait+irq+softIrq) * 100) / total,
2856 (user * 100) / total,
2857 (system * 100) / total,
2858 (iowait * 100) / total,
2859 (irq * 100) / total,
2860 (softIrq * 100) / total);
2865 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2866 synchronized(bstats) {
2867 synchronized(mPidsSelfLocked) {
2868 if (haveNewCpuStats) {
2869 if (bstats.startAddingCpuLocked()) {
2872 final int N = mProcessCpuTracker.countStats();
2873 for (int i=0; i<N; i++) {
2874 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2878 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2879 totalUTime += st.rel_utime;
2880 totalSTime += st.rel_stime;
2882 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2883 if (ps == null || !ps.isActive()) {
2884 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2885 pr.info.uid, pr.processName);
2887 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2888 pr.curCpuTime += st.rel_utime + st.rel_stime;
2890 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2891 if (ps == null || !ps.isActive()) {
2892 st.batteryStats = ps = bstats.getProcessStatsLocked(
2893 bstats.mapUid(st.uid), st.name);
2895 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2898 final int userTime = mProcessCpuTracker.getLastUserTime();
2899 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2900 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2901 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2902 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2903 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2904 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2905 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2910 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2911 mLastWriteTime = now;
2912 mBatteryStatsService.scheduleWriteToDisk();
2919 public void batteryNeedsCpuUpdate() {
2920 updateCpuStatsNow();
2924 public void batteryPowerChanged(boolean onBattery) {
2925 // When plugging in, update the CPU stats first before changing
2927 updateCpuStatsNow();
2928 synchronized (this) {
2929 synchronized(mPidsSelfLocked) {
2930 mOnBattery = DEBUG_POWER ? true : onBattery;
2936 public void batterySendBroadcast(Intent intent) {
2937 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2938 AppOpsManager.OP_NONE, null, false, false,
2939 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2943 * Initialize the application bind args. These are passed to each
2944 * process when the bindApplication() IPC is sent to the process. They're
2945 * lazily setup to make sure the services are running when they're asked for.
2947 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2948 // Isolated processes won't get this optimization, so that we don't
2949 // violate the rules about which services they have access to.
2951 if (mIsolatedAppBindArgs == null) {
2952 mIsolatedAppBindArgs = new HashMap<>();
2953 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2955 return mIsolatedAppBindArgs;
2958 if (mAppBindArgs == null) {
2959 mAppBindArgs = new HashMap<>();
2961 // Setup the application init args
2962 mAppBindArgs.put("package", ServiceManager.getService("package"));
2963 mAppBindArgs.put("window", ServiceManager.getService("window"));
2964 mAppBindArgs.put(Context.ALARM_SERVICE,
2965 ServiceManager.getService(Context.ALARM_SERVICE));
2967 return mAppBindArgs;
2970 boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2971 if (r == null || mFocusedActivity == r) {
2975 if (!r.isFocusable()) {
2976 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2980 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2982 final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2983 if (wasDoingSetFocusedActivity) Slog.w(TAG,
2984 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2985 mDoingSetFocusedActivity = true;
2987 final ActivityRecord last = mFocusedActivity;
2988 mFocusedActivity = r;
2989 if (r.task.isApplicationTask()) {
2990 if (mCurAppTimeTracker != r.appTimeTracker) {
2991 // We are switching app tracking. Complete the current one.
2992 if (mCurAppTimeTracker != null) {
2993 mCurAppTimeTracker.stop();
2994 mHandler.obtainMessage(
2995 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2996 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2997 mCurAppTimeTracker = null;
2999 if (r.appTimeTracker != null) {
3000 mCurAppTimeTracker = r.appTimeTracker;
3001 startTimeTrackingFocusedActivityLocked();
3004 startTimeTrackingFocusedActivityLocked();
3007 r.appTimeTracker = null;
3009 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3010 // TODO: Probably not, because we don't want to resume voice on switching
3011 // back to this activity
3012 if (r.task.voiceInteractor != null) {
3013 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3015 finishRunningVoiceLocked();
3016 IVoiceInteractionSession session;
3017 if (last != null && ((session = last.task.voiceSession) != null
3018 || (session = last.voiceSession) != null)) {
3019 // We had been in a voice interaction session, but now focused has
3020 // move to something different. Just finish the session, we can't
3021 // return to it and retain the proper state and synchronization with
3022 // the voice interaction service.
3023 finishVoiceTask(session);
3026 if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3027 mWindowManager.setFocusedApp(r.appToken, true);
3029 applyUpdateLockStateLocked(r);
3030 applyUpdateVrModeLocked(r);
3031 if (mFocusedActivity.userId != mLastFocusedUserId) {
3032 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3033 mHandler.obtainMessage(
3034 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3035 mLastFocusedUserId = mFocusedActivity.userId;
3038 // Log a warning if the focused app is changed during the process. This could
3039 // indicate a problem of the focus setting logic!
3040 if (mFocusedActivity != r) Slog.w(TAG,
3041 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3042 mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3044 EventLogTags.writeAmFocusedActivity(
3045 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3046 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3051 final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3052 if (mFocusedActivity != goingAway) {
3056 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3057 if (focusedStack != null) {
3058 final ActivityRecord top = focusedStack.topActivity();
3059 if (top != null && top.userId != mLastFocusedUserId) {
3060 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3061 mHandler.sendMessage(
3062 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3063 mLastFocusedUserId = top.userId;
3067 // Try to move focus to another activity if possible.
3068 if (setFocusedActivityLocked(
3069 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3073 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3074 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3075 mFocusedActivity = null;
3076 EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3080 public void setFocusedStack(int stackId) {
3081 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3082 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3083 final long callingId = Binder.clearCallingIdentity();
3085 synchronized (this) {
3086 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3087 if (stack == null) {
3090 final ActivityRecord r = stack.topRunningActivityLocked();
3091 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3092 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3096 Binder.restoreCallingIdentity(callingId);
3101 public void setFocusedTask(int taskId) {
3102 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3103 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3104 final long callingId = Binder.clearCallingIdentity();
3106 synchronized (this) {
3107 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3111 if (mUserController.shouldConfirmCredentials(task.userId)) {
3112 mActivityStarter.showConfirmDeviceCredential(task.userId);
3113 if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3114 mStackSupervisor.moveTaskToStackLocked(task.taskId,
3115 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3116 "setFocusedTask", ANIMATE);
3120 final ActivityRecord r = task.topRunningActivityLocked();
3121 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3122 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3126 Binder.restoreCallingIdentity(callingId);
3130 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3132 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3133 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3134 synchronized (this) {
3135 if (listener != null) {
3136 mTaskStackListeners.register(listener);
3142 public void notifyActivityDrawn(IBinder token) {
3143 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3144 synchronized (this) {
3145 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3147 r.task.stack.notifyActivityDrawnLocked(r);
3152 final void applyUpdateLockStateLocked(ActivityRecord r) {
3153 // Modifications to the UpdateLock state are done on our handler, outside
3154 // the activity manager's locks. The new state is determined based on the
3155 // state *now* of the relevant activity record. The object is passed to
3156 // the handler solely for logging detail, not to be consulted/modified.
3157 final boolean nextState = r != null && r.immersive;
3158 mHandler.sendMessage(
3159 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3162 final void applyUpdateVrModeLocked(ActivityRecord r) {
3163 mHandler.sendMessage(
3164 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3167 private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3168 mHandler.sendMessage(
3169 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3172 private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3173 ComponentName callingPackage, boolean immediate) {
3174 VrManagerInternal vrService =
3175 LocalServices.getService(VrManagerInternal.class);
3177 vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3179 vrService.setVrMode(enabled, packageName, userId, callingPackage);
3183 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3184 Message msg = Message.obtain();
3185 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3186 msg.obj = r.task.askedCompatMode ? null : r;
3187 mUiHandler.sendMessage(msg);
3190 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3191 if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3192 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3193 final Message msg = Message.obtain();
3194 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3196 mUiHandler.sendMessage(msg);
3200 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3201 String what, Object obj, ProcessRecord srcApp) {
3202 app.lastActivityTime = now;
3204 if (app.activities.size() > 0) {
3205 // Don't want to touch dependent processes that are hosting activities.
3209 int lrui = mLruProcesses.lastIndexOf(app);
3211 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3212 + what + " " + obj + " from " + srcApp);
3216 if (lrui >= index) {
3217 // Don't want to cause this to move dependent processes *back* in the
3218 // list as if they were less frequently used.
3222 if (lrui >= mLruProcessActivityStart) {
3223 // Don't want to touch dependent processes that are hosting activities.
3227 mLruProcesses.remove(lrui);
3231 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3232 + " in LRU list: " + app);
3233 mLruProcesses.add(index, app);
3237 static void killProcessGroup(int uid, int pid) {
3238 if (sKillHandler != null) {
3239 sKillHandler.sendMessage(
3240 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3242 Slog.w(TAG, "Asked to kill process group before system bringup!");
3243 Process.killProcessGroup(uid, pid);
3247 final void removeLruProcessLocked(ProcessRecord app) {
3248 int lrui = mLruProcesses.lastIndexOf(app);
3251 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3252 Process.killProcessQuiet(app.pid);
3253 killProcessGroup(app.uid, app.pid);
3255 if (lrui <= mLruProcessActivityStart) {
3256 mLruProcessActivityStart--;
3258 if (lrui <= mLruProcessServiceStart) {
3259 mLruProcessServiceStart--;
3261 mLruProcesses.remove(lrui);
3265 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3266 ProcessRecord client) {
3267 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3268 || app.treatLikeActivity;
3269 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3270 if (!activityChange && hasActivity) {
3271 // The process has activities, so we are only allowing activity-based adjustments
3272 // to move it. It should be kept in the front of the list with other
3273 // processes that have activities, and we don't want those to change their
3274 // order except due to activity operations.
3279 final long now = SystemClock.uptimeMillis();
3280 app.lastActivityTime = now;
3282 // First a quick reject: if the app is already at the position we will
3283 // put it, then there is nothing to do.
3285 final int N = mLruProcesses.size();
3286 if (N > 0 && mLruProcesses.get(N-1) == app) {
3287 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3291 if (mLruProcessServiceStart > 0
3292 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3293 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3298 int lrui = mLruProcesses.lastIndexOf(app);
3300 if (app.persistent && lrui >= 0) {
3301 // We don't care about the position of persistent processes, as long as
3302 // they are in the list.
3303 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3307 /* In progress: compute new position first, so we can avoid doing work
3308 if the process is not actually going to move. Not yet working.
3311 boolean inActivity = false, inService = false;
3313 // Process has activities, put it at the very tipsy-top.
3314 addIndex = mLruProcesses.size();
3315 nextIndex = mLruProcessServiceStart;
3317 } else if (hasService) {
3318 // Process has services, put it at the top of the service list.
3319 addIndex = mLruProcessActivityStart;
3320 nextIndex = mLruProcessServiceStart;
3324 // Process not otherwise of interest, it goes to the top of the non-service area.
3325 addIndex = mLruProcessServiceStart;
3326 if (client != null) {
3327 int clientIndex = mLruProcesses.lastIndexOf(client);
3328 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3330 if (clientIndex >= 0 && addIndex > clientIndex) {
3331 addIndex = clientIndex;
3334 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3337 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3338 + mLruProcessActivityStart + "): " + app);
3342 if (lrui < mLruProcessActivityStart) {
3343 mLruProcessActivityStart--;
3345 if (lrui < mLruProcessServiceStart) {
3346 mLruProcessServiceStart--;
3349 if (addIndex > lrui) {
3352 if (nextIndex > lrui) {
3356 mLruProcesses.remove(lrui);
3360 mLruProcesses.add(addIndex, app);
3362 mLruProcessActivityStart++;
3365 mLruProcessActivityStart++;
3371 final int N = mLruProcesses.size();
3372 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3373 // Process doesn't have activities, but has clients with
3374 // activities... move it up, but one below the top (the top
3375 // should always have a real activity).
3376 if (DEBUG_LRU) Slog.d(TAG_LRU,
3377 "Adding to second-top of LRU activity list: " + app);
3378 mLruProcesses.add(N - 1, app);
3379 // To keep it from spamming the LRU list (by making a bunch of clients),
3380 // we will push down any other entries owned by the app.
3381 final int uid = app.info.uid;
3382 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3383 ProcessRecord subProc = mLruProcesses.get(i);
3384 if (subProc.info.uid == uid) {
3385 // We want to push this one down the list. If the process after
3386 // it is for the same uid, however, don't do so, because we don't
3387 // want them internally to be re-ordered.
3388 if (mLruProcesses.get(i - 1).info.uid != uid) {
3389 if (DEBUG_LRU) Slog.d(TAG_LRU,
3390 "Pushing uid " + uid + " swapping at " + i + ": "
3391 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3392 ProcessRecord tmp = mLruProcesses.get(i);
3393 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3394 mLruProcesses.set(i - 1, tmp);
3398 // A gap, we can stop here.
3403 // Process has activities, put it at the very tipsy-top.
3404 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3405 mLruProcesses.add(app);
3407 nextIndex = mLruProcessServiceStart;
3408 } else if (hasService) {
3409 // Process has services, put it at the top of the service list.
3410 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3411 mLruProcesses.add(mLruProcessActivityStart, app);
3412 nextIndex = mLruProcessServiceStart;
3413 mLruProcessActivityStart++;
3415 // Process not otherwise of interest, it goes to the top of the non-service area.
3416 int index = mLruProcessServiceStart;
3417 if (client != null) {
3418 // If there is a client, don't allow the process to be moved up higher
3419 // in the list than that client.
3420 int clientIndex = mLruProcesses.lastIndexOf(client);
3421 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3422 + " when updating " + app);
3423 if (clientIndex <= lrui) {
3424 // Don't allow the client index restriction to push it down farther in the
3425 // list than it already is.
3428 if (clientIndex >= 0 && index > clientIndex) {
3429 index = clientIndex;
3432 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3433 mLruProcesses.add(index, app);
3434 nextIndex = index-1;
3435 mLruProcessActivityStart++;
3436 mLruProcessServiceStart++;
3439 // If the app is currently using a content provider or service,
3440 // bump those processes as well.
3441 for (int j=app.connections.size()-1; j>=0; j--) {
3442 ConnectionRecord cr = app.connections.valueAt(j);
3443 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3444 && cr.binding.service.app != null
3445 && cr.binding.service.app.lruSeq != mLruSeq
3446 && !cr.binding.service.app.persistent) {
3447 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3448 "service connection", cr, app);
3451 for (int j=app.conProviders.size()-1; j>=0; j--) {
3452 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3453 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3454 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3455 "provider reference", cpr, app);
3460 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3461 if (uid == Process.SYSTEM_UID) {
3462 // The system gets to run in any process. If there are multiple
3463 // processes with the same uid, just pick the first (this
3464 // should never happen).
3465 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3466 if (procs == null) return null;
3467 final int procCount = procs.size();
3468 for (int i = 0; i < procCount; i++) {
3469 final int procUid = procs.keyAt(i);
3470 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3471 // Don't use an app process or different user process for system component.
3474 return procs.valueAt(i);
3477 ProcessRecord proc = mProcessNames.get(processName, uid);
3478 if (false && proc != null && !keepIfLarge
3479 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3480 && proc.lastCachedPss >= 4000) {
3481 // Turn this condition on to cause killing to happen regularly, for testing.
3482 if (proc.baseProcessTracker != null) {
3483 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3485 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3486 } else if (proc != null && !keepIfLarge
3487 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3488 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3489 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3490 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3491 if (proc.baseProcessTracker != null) {
3492 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3494 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3500 void notifyPackageUse(String packageName, int reason) {
3501 IPackageManager pm = AppGlobals.getPackageManager();
3503 pm.notifyPackageUse(packageName, reason);
3504 } catch (RemoteException e) {
3508 boolean isNextTransitionForward() {
3509 int transit = mWindowManager.getPendingAppTransition();
3510 return transit == TRANSIT_ACTIVITY_OPEN
3511 || transit == TRANSIT_TASK_OPEN
3512 || transit == TRANSIT_TASK_TO_FRONT;
3515 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3516 String processName, String abiOverride, int uid, Runnable crashHandler) {
3517 synchronized(this) {
3518 ApplicationInfo info = new ApplicationInfo();
3519 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3520 // For isolated processes, the former contains the parent's uid and the latter the
3521 // actual uid of the isolated process.
3522 // In the special case introduced by this method (which is, starting an isolated
3523 // process directly from the SystemServer without an actual parent app process) the
3524 // closest thing to a parent's uid is SYSTEM_UID.
3525 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3526 // the |isolated| logic in the ProcessRecord constructor.
3527 info.uid = Process.SYSTEM_UID;
3528 info.processName = processName;
3529 info.className = entryPoint;
3530 info.packageName = "android";
3531 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3532 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3533 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3534 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3536 return proc != null ? proc.pid : 0;
3540 final ProcessRecord startProcessLocked(String processName,
3541 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3542 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3543 boolean isolated, boolean keepIfLarge) {
3544 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3545 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3546 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3547 null /* crashHandler */);
3550 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3551 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3552 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3553 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3554 long startTime = SystemClock.elapsedRealtime();
3557 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3558 checkTime(startTime, "startProcess: after getProcessRecord");
3560 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3561 // If we are in the background, then check to see if this process
3562 // is bad. If so, we will just silently fail.
3563 if (mAppErrors.isBadProcessLocked(info)) {
3564 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3565 + "/" + info.processName);
3569 // When the user is explicitly starting a process, then clear its
3570 // crash count so that we won't make it bad until they see at
3571 // least one crash dialog again, and make the process good again
3572 // if it had been bad.
3573 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3574 + "/" + info.processName);
3575 mAppErrors.resetProcessCrashTimeLocked(info);
3576 if (mAppErrors.isBadProcessLocked(info)) {
3577 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3578 UserHandle.getUserId(info.uid), info.uid,
3580 mAppErrors.clearBadProcessLocked(info);
3587 // If this is an isolated process, it can't re-use an existing process.
3591 // app launch boost for big.little configurations
3592 // use cpusets to migrate freshly launched tasks to big cores
3593 nativeMigrateToBoost();
3595 mBoostStartTime = SystemClock.uptimeMillis();
3596 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3597 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3599 // We don't have to do anything more if:
3600 // (1) There is an existing application record; and
3601 // (2) The caller doesn't think it is dead, OR there is no thread
3602 // object attached to it so we know it couldn't have crashed; and
3603 // (3) There is a pid assigned to it, so it is either starting or
3605 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3606 + " app=" + app + " knownToBeDead=" + knownToBeDead
3607 + " thread=" + (app != null ? app.thread : null)
3608 + " pid=" + (app != null ? app.pid : -1));
3609 if (app != null && app.pid > 0) {
3610 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3611 // We already have the app running, or are waiting for it to
3612 // come up (we have a pid but not yet its thread), so keep it.
3613 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3614 // If this is a new package in the process, add the package to the list
3615 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3616 checkTime(startTime, "startProcess: done, added package to proc");
3620 // An application record is attached to a previous process,
3622 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3623 checkTime(startTime, "startProcess: bad proc running, killing");
3624 killProcessGroup(app.uid, app.pid);
3625 handleAppDiedLocked(app, true, true);
3626 checkTime(startTime, "startProcess: done killing old proc");
3629 String hostingNameStr = hostingName != null
3630 ? hostingName.flattenToShortString() : null;
3633 checkTime(startTime, "startProcess: creating new process record");
3634 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3636 Slog.w(TAG, "Failed making new process record for "
3637 + processName + "/" + info.uid + " isolated=" + isolated);
3640 app.crashHandler = crashHandler;
3641 checkTime(startTime, "startProcess: done creating new process record");
3643 // If this is a new package in the process, add the package to the list
3644 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3645 checkTime(startTime, "startProcess: added package to existing proc");
3648 // If the system is not ready yet, then hold off on starting this
3649 // process until it is.
3650 if (!mProcessesReady
3651 && !isAllowedWhileBooting(info)
3652 && !allowWhileBooting) {
3653 if (!mProcessesOnHold.contains(app)) {
3654 mProcessesOnHold.add(app);
3656 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3657 "System not ready, putting on hold: " + app);
3658 checkTime(startTime, "startProcess: returning with proc on hold");
3662 checkTime(startTime, "startProcess: stepping in to startProcess");
3664 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3665 checkTime(startTime, "startProcess: done starting proc!");
3666 return (app.pid != 0) ? app : null;
3669 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3670 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3673 private final void startProcessLocked(ProcessRecord app,
3674 String hostingType, String hostingNameStr) {
3675 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3676 null /* entryPoint */, null /* entryPointArgs */);
3679 private final void startProcessLocked(ProcessRecord app, String hostingType,
3680 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3681 long startTime = SystemClock.elapsedRealtime();
3682 if (app.pid > 0 && app.pid != MY_PID) {
3683 checkTime(startTime, "startProcess: removing from pids map");
3684 synchronized (mPidsSelfLocked) {
3685 mPidsSelfLocked.remove(app.pid);
3686 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3688 checkTime(startTime, "startProcess: done removing from pids map");
3692 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3693 "startProcessLocked removing on hold: " + app);
3694 mProcessesOnHold.remove(app);
3696 checkTime(startTime, "startProcess: starting to update cpu stats");
3698 checkTime(startTime, "startProcess: done updating cpu stats");
3702 final int userId = UserHandle.getUserId(app.uid);
3703 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3704 } catch (RemoteException e) {
3705 throw e.rethrowAsRuntimeException();
3710 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3711 if (!app.isolated) {
3712 int[] permGids = null;
3714 checkTime(startTime, "startProcess: getting gids from package manager");
3715 final IPackageManager pm = AppGlobals.getPackageManager();
3716 permGids = pm.getPackageGids(app.info.packageName,
3717 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3718 MountServiceInternal mountServiceInternal = LocalServices.getService(
3719 MountServiceInternal.class);
3720 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3721 app.info.packageName);
3722 } catch (RemoteException e) {
3723 throw e.rethrowAsRuntimeException();
3727 * Add shared application and profile GIDs so applications can share some
3728 * resources like shared libraries and access user-wide resources
3730 if (ArrayUtils.isEmpty(permGids)) {
3733 gids = new int[permGids.length + 2];
3734 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3736 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3737 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3739 checkTime(startTime, "startProcess: building args");
3740 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3741 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3742 && mTopComponent != null
3743 && app.processName.equals(mTopComponent.getPackageName())) {
3746 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3747 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3752 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3753 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3754 // Also turn on CheckJNI for debuggable apps. It's quite
3755 // awkward to turn on otherwise.
3756 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3758 // Run the app in safe mode if its manifest requests so or the
3759 // system is booted in safe mode.
3760 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3761 mSafeMode == true) {
3762 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3764 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3765 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3767 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3768 if ("true".equals(genDebugInfoProperty)) {
3769 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3771 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3772 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3774 if ("1".equals(SystemProperties.get("debug.assert"))) {
3775 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3777 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3778 // Enable all debug flags required by the native debugger.
3779 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3780 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3781 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3782 mNativeDebuggingApp = null;
3785 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3786 if (requiredAbi == null) {
3787 requiredAbi = Build.SUPPORTED_ABIS[0];
3790 String instructionSet = null;
3791 if (app.info.primaryCpuAbi != null) {
3792 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3796 app.requiredAbi = requiredAbi;
3797 app.instructionSet = instructionSet;
3799 // Start the process. It will either succeed and return a result containing
3800 // the PID of the new process, or else throw a RuntimeException.
3801 boolean isActivityProcess = (entryPoint == null);
3802 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3803 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3805 checkTime(startTime, "startProcess: asking zygote to start proc");
3806 Process.ProcessStartResult startResult = Process.start(entryPoint,
3807 app.processName, uid, uid, gids, debugFlags, mountExternal,
3808 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3809 app.info.dataDir, entryPointArgs);
3810 checkTime(startTime, "startProcess: returned from zygote!");
3811 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3813 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3814 checkTime(startTime, "startProcess: done updating battery stats");
3816 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3817 UserHandle.getUserId(uid), startResult.pid, uid,
3818 app.processName, hostingType,
3819 hostingNameStr != null ? hostingNameStr : "");
3822 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3823 app.info.seinfo, app.info.sourceDir, startResult.pid);
3824 } catch (RemoteException ex) {
3828 if (app.persistent) {
3829 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3832 checkTime(startTime, "startProcess: building log message");
3833 StringBuilder buf = mStringBuilder;
3835 buf.append("Start proc ");
3836 buf.append(startResult.pid);
3838 buf.append(app.processName);
3840 UserHandle.formatUid(buf, uid);
3841 if (!isActivityProcess) {
3843 buf.append(entryPoint);
3846 buf.append(" for ");
3847 buf.append(hostingType);
3848 if (hostingNameStr != null) {
3850 buf.append(hostingNameStr);
3852 Slog.i(TAG, buf.toString());
3853 app.setPid(startResult.pid);
3854 app.usingWrapper = startResult.usingWrapper;
3855 app.removed = false;
3857 app.killedByAm = false;
3858 checkTime(startTime, "startProcess: starting to update pids map");
3859 ProcessRecord oldApp;
3860 synchronized (mPidsSelfLocked) {
3861 oldApp = mPidsSelfLocked.get(startResult.pid);
3863 // If there is already an app occupying that pid that hasn't been cleaned up
3864 if (oldApp != null && !app.isolated) {
3865 // Clean up anything relating to this pid first
3866 Slog.w(TAG, "Reusing pid " + startResult.pid
3867 + " while app is still mapped to it");
3868 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3869 true /*replacingPid*/);
3871 synchronized (mPidsSelfLocked) {
3872 this.mPidsSelfLocked.put(startResult.pid, app);
3873 if (isActivityProcess) {
3874 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3876 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3877 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3880 checkTime(startTime, "startProcess: done updating pids map");
3881 } catch (RuntimeException e) {
3882 Slog.e(TAG, "Failure starting process " + app.processName, e);
3884 // Something went very wrong while trying to start this process; one
3885 // common case is when the package is frozen due to an active
3886 // upgrade. To recover, clean up any active bookkeeping related to
3887 // starting this process. (We already invoked this method once when
3888 // the package was initially frozen through KILL_APPLICATION_MSG, so
3889 // it doesn't hurt to use it again.)
3890 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3891 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3895 void updateUsageStats(ActivityRecord component, boolean resumed) {
3896 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3897 "updateUsageStats: comp=" + component + "res=" + resumed);
3898 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3900 if (mUsageStatsService != null) {
3901 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902 UsageEvents.Event.MOVE_TO_FOREGROUND);
3904 synchronized (stats) {
3905 stats.noteActivityResumedLocked(component.app.uid);
3908 if (mUsageStatsService != null) {
3909 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3910 UsageEvents.Event.MOVE_TO_BACKGROUND);
3912 synchronized (stats) {
3913 stats.noteActivityPausedLocked(component.app.uid);
3918 Intent getHomeIntent() {
3919 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3920 intent.setComponent(mTopComponent);
3921 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3922 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3923 intent.addCategory(Intent.CATEGORY_HOME);
3928 boolean startHomeActivityLocked(int userId, String reason) {
3929 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3930 && mTopAction == null) {
3931 // We are running in factory test mode, but unable to find
3932 // the factory test app, so just sit around displaying the
3933 // error message and don't try to start anything.
3936 Intent intent = getHomeIntent();
3937 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3938 if (aInfo != null) {
3939 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3940 // Don't do this if the home app is currently being
3942 aInfo = new ActivityInfo(aInfo);
3943 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3944 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3945 aInfo.applicationInfo.uid, true);
3946 if (app == null || app.instrumentationClass == null) {
3947 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3948 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3951 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3957 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3958 ActivityInfo ai = null;
3959 ComponentName comp = intent.getComponent();
3963 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3965 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3967 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3971 ai = info.activityInfo;
3974 } catch (RemoteException e) {
3982 * Starts the "new version setup screen" if appropriate.
3984 void startSetupActivityLocked() {
3985 // Only do this once per boot.
3986 if (mCheckedForSetup) {
3990 // We will show this screen if the current one is a different
3991 // version than the last one shown, and we are not running in
3992 // low-level factory test mode.
3993 final ContentResolver resolver = mContext.getContentResolver();
3994 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3995 Settings.Global.getInt(resolver,
3996 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3997 mCheckedForSetup = true;
3999 // See if we should be showing the platform update setup UI.
4000 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4001 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4002 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4003 if (!ris.isEmpty()) {
4004 final ResolveInfo ri = ris.get(0);
4005 String vers = ri.activityInfo.metaData != null
4006 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4008 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4009 vers = ri.activityInfo.applicationInfo.metaData.getString(
4010 Intent.METADATA_SETUP_VERSION);
4012 String lastVers = Settings.Secure.getString(
4013 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4014 if (vers != null && !vers.equals(lastVers)) {
4015 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4016 intent.setComponent(new ComponentName(
4017 ri.activityInfo.packageName, ri.activityInfo.name));
4018 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4019 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4020 null, 0, 0, 0, null, false, false, null, null, null);
4026 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4027 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4030 void enforceNotIsolatedCaller(String caller) {
4031 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4032 throw new SecurityException("Isolated process not allowed to call " + caller);
4036 void enforceShellRestriction(String restriction, int userHandle) {
4037 if (Binder.getCallingUid() == Process.SHELL_UID) {
4038 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4039 throw new SecurityException("Shell does not have permission to access user "
4046 public int getFrontActivityScreenCompatMode() {
4047 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4048 synchronized (this) {
4049 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4054 public void setFrontActivityScreenCompatMode(int mode) {
4055 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4056 "setFrontActivityScreenCompatMode");
4057 synchronized (this) {
4058 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4063 public int getPackageScreenCompatMode(String packageName) {
4064 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4065 synchronized (this) {
4066 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4071 public void setPackageScreenCompatMode(String packageName, int mode) {
4072 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4073 "setPackageScreenCompatMode");
4074 synchronized (this) {
4075 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4080 public boolean getPackageAskScreenCompat(String packageName) {
4081 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4082 synchronized (this) {
4083 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4088 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4089 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4090 "setPackageAskScreenCompat");
4091 synchronized (this) {
4092 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4096 private boolean hasUsageStatsPermission(String callingPackage) {
4097 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4098 Binder.getCallingUid(), callingPackage);
4099 if (mode == AppOpsManager.MODE_DEFAULT) {
4100 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4101 == PackageManager.PERMISSION_GRANTED;
4103 return mode == AppOpsManager.MODE_ALLOWED;
4107 public int getPackageProcessState(String packageName, String callingPackage) {
4108 if (!hasUsageStatsPermission(callingPackage)) {
4109 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4110 "getPackageProcessState");
4113 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4114 synchronized (this) {
4115 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4116 final ProcessRecord proc = mLruProcesses.get(i);
4117 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4118 || procState > proc.setProcState) {
4119 boolean found = false;
4120 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4121 if (proc.pkgList.keyAt(j).equals(packageName)) {
4122 procState = proc.setProcState;
4126 if (proc.pkgDeps != null && !found) {
4127 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4128 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4129 procState = proc.setProcState;
4141 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4142 synchronized (this) {
4143 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4147 if (app.trimMemoryLevel < level && app.thread != null &&
4148 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4149 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4151 app.thread.scheduleTrimMemory(level);
4152 app.trimMemoryLevel = level;
4154 } catch (RemoteException e) {
4155 // Fallthrough to failure case.
4162 private void dispatchProcessesChanged() {
4164 synchronized (this) {
4165 N = mPendingProcessChanges.size();
4166 if (mActiveProcessChanges.length < N) {
4167 mActiveProcessChanges = new ProcessChangeItem[N];
4169 mPendingProcessChanges.toArray(mActiveProcessChanges);
4170 mPendingProcessChanges.clear();
4171 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4172 "*** Delivering " + N + " process changes");
4175 int i = mProcessObservers.beginBroadcast();
4178 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4179 if (observer != null) {
4181 for (int j=0; j<N; j++) {
4182 ProcessChangeItem item = mActiveProcessChanges[j];
4183 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4184 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4185 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4186 + item.uid + ": " + item.foregroundActivities);
4187 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4188 item.foregroundActivities);
4190 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4191 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4192 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4193 + ": " + item.processState);
4194 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4197 } catch (RemoteException e) {
4201 mProcessObservers.finishBroadcast();
4203 synchronized (this) {
4204 for (int j=0; j<N; j++) {
4205 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4210 private void dispatchProcessDied(int pid, int uid) {
4211 int i = mProcessObservers.beginBroadcast();
4214 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4215 if (observer != null) {
4217 observer.onProcessDied(pid, uid);
4218 } catch (RemoteException e) {
4222 mProcessObservers.finishBroadcast();
4225 private void dispatchUidsChanged() {
4227 synchronized (this) {
4228 N = mPendingUidChanges.size();
4229 if (mActiveUidChanges.length < N) {
4230 mActiveUidChanges = new UidRecord.ChangeItem[N];
4232 for (int i=0; i<N; i++) {
4233 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4234 mActiveUidChanges[i] = change;
4235 if (change.uidRecord != null) {
4236 change.uidRecord.pendingChange = null;
4237 change.uidRecord = null;
4240 mPendingUidChanges.clear();
4241 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4242 "*** Delivering " + N + " uid changes");
4245 if (mLocalPowerManager != null) {
4246 for (int j=0; j<N; j++) {
4247 UidRecord.ChangeItem item = mActiveUidChanges[j];
4248 if (item.change == UidRecord.CHANGE_GONE
4249 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4250 mLocalPowerManager.uidGone(item.uid);
4252 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4257 int i = mUidObservers.beginBroadcast();
4260 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4261 final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4262 if (observer != null) {
4264 for (int j=0; j<N; j++) {
4265 UidRecord.ChangeItem item = mActiveUidChanges[j];
4266 final int change = item.change;
4267 UidRecord validateUid = null;
4268 if (VALIDATE_UID_STATES && i == 0) {
4269 validateUid = mValidateUids.get(item.uid);
4270 if (validateUid == null && change != UidRecord.CHANGE_GONE
4271 && change != UidRecord.CHANGE_GONE_IDLE) {
4272 validateUid = new UidRecord(item.uid);
4273 mValidateUids.put(item.uid, validateUid);
4276 if (change == UidRecord.CHANGE_IDLE
4277 || change == UidRecord.CHANGE_GONE_IDLE) {
4278 if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4279 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4280 "UID idle uid=" + item.uid);
4281 observer.onUidIdle(item.uid);
4283 if (VALIDATE_UID_STATES && i == 0) {
4284 if (validateUid != null) {
4285 validateUid.idle = true;
4288 } else if (change == UidRecord.CHANGE_ACTIVE) {
4289 if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4290 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4291 "UID active uid=" + item.uid);
4292 observer.onUidActive(item.uid);
4294 if (VALIDATE_UID_STATES && i == 0) {
4295 validateUid.idle = false;
4298 if (change == UidRecord.CHANGE_GONE
4299 || change == UidRecord.CHANGE_GONE_IDLE) {
4300 if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4301 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4302 "UID gone uid=" + item.uid);
4303 observer.onUidGone(item.uid);
4305 if (VALIDATE_UID_STATES && i == 0) {
4306 if (validateUid != null) {
4307 mValidateUids.remove(item.uid);
4311 if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4312 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4313 "UID CHANGED uid=" + item.uid
4314 + ": " + item.processState);
4315 observer.onUidStateChanged(item.uid, item.processState);
4317 if (VALIDATE_UID_STATES && i == 0) {
4318 validateUid.curProcState = validateUid.setProcState
4319 = item.processState;
4323 } catch (RemoteException e) {
4327 mUidObservers.finishBroadcast();
4329 synchronized (this) {
4330 for (int j=0; j<N; j++) {
4331 mAvailUidChanges.add(mActiveUidChanges[j]);
4337 public final int startActivity(IApplicationThread caller, String callingPackage,
4338 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4339 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4340 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4341 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4342 UserHandle.getCallingUserId());
4345 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4346 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4347 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4348 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4349 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4351 // TODO: Switch to user app stacks here.
4352 String mimeType = intent.getType();
4353 final Uri data = intent.getData();
4354 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4355 mimeType = getProviderMimeType(data, userId);
4357 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4359 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4360 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4361 null, 0, 0, null, null, null, null, false, userId, container, null);
4365 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4366 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4367 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4368 enforceNotIsolatedCaller("startActivity");
4369 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4370 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4371 // TODO: Switch to user app stacks here.
4372 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4373 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4374 profilerInfo, null, null, bOptions, false, userId, null, null);
4378 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4379 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4380 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4383 // This is very dangerous -- it allows you to perform a start activity (including
4384 // permission grants) as any app that may launch one of your own activities. So
4385 // we will only allow this to be done from activities that are part of the core framework,
4386 // and then only when they are running as the system.
4387 final ActivityRecord sourceRecord;
4388 final int targetUid;
4389 final String targetPackage;
4390 synchronized (this) {
4391 if (resultTo == null) {
4392 throw new SecurityException("Must be called from an activity");
4394 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4395 if (sourceRecord == null) {
4396 throw new SecurityException("Called with bad activity token: " + resultTo);
4398 if (!sourceRecord.info.packageName.equals("android")) {
4399 throw new SecurityException(
4400 "Must be called from an activity that is declared in the android package");
4402 if (sourceRecord.app == null) {
4403 throw new SecurityException("Called without a process attached to activity");
4405 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4406 // This is still okay, as long as this activity is running under the
4407 // uid of the original calling activity.
4408 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4409 throw new SecurityException(
4410 "Calling activity in uid " + sourceRecord.app.uid
4411 + " must be system uid or original calling uid "
4412 + sourceRecord.launchedFromUid);
4415 if (ignoreTargetSecurity) {
4416 if (intent.getComponent() == null) {
4417 throw new SecurityException(
4418 "Component must be specified with ignoreTargetSecurity");
4420 if (intent.getSelector() != null) {
4421 throw new SecurityException(
4422 "Selector not allowed with ignoreTargetSecurity");
4425 targetUid = sourceRecord.launchedFromUid;
4426 targetPackage = sourceRecord.launchedFromPackage;
4429 if (userId == UserHandle.USER_NULL) {
4430 userId = UserHandle.getUserId(sourceRecord.app.uid);
4433 // TODO: Switch to user app stacks here.
4435 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4436 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4437 null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4439 } catch (SecurityException e) {
4440 // XXX need to figure out how to propagate to original app.
4441 // A SecurityException here is generally actually a fault of the original
4442 // calling activity (such as a fairly granting permissions), so propagate it
4445 StringBuilder msg = new StringBuilder();
4446 msg.append("While launching");
4447 msg.append(intent.toString());
4449 msg.append(e.getMessage());
4456 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4457 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4458 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4459 enforceNotIsolatedCaller("startActivityAndWait");
4460 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4461 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4462 WaitResult res = new WaitResult();
4463 // TODO: Switch to user app stacks here.
4464 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4465 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4466 bOptions, false, userId, null, null);
4471 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4472 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4473 int startFlags, Configuration config, Bundle bOptions, int userId) {
4474 enforceNotIsolatedCaller("startActivityWithConfig");
4475 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4476 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4477 // TODO: Switch to user app stacks here.
4478 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4479 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4480 null, null, config, bOptions, false, userId, null, null);
4485 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4486 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4487 int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4488 throws TransactionTooLargeException {
4489 enforceNotIsolatedCaller("startActivityIntentSender");
4490 // Refuse possible leaked file descriptors
4491 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4492 throw new IllegalArgumentException("File descriptors passed in Intent");
4495 IIntentSender sender = intent.getTarget();
4496 if (!(sender instanceof PendingIntentRecord)) {
4497 throw new IllegalArgumentException("Bad PendingIntent object");
4500 PendingIntentRecord pir = (PendingIntentRecord)sender;
4502 synchronized (this) {
4503 // If this is coming from the currently resumed activity, it is
4504 // effectively saying that app switches are allowed at this point.
4505 final ActivityStack stack = getFocusedStack();
4506 if (stack.mResumedActivity != null &&
4507 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4508 mAppSwitchesAllowedTime = 0;
4511 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4512 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4517 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4518 Intent intent, String resolvedType, IVoiceInteractionSession session,
4519 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4520 Bundle bOptions, int userId) {
4521 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4522 != PackageManager.PERMISSION_GRANTED) {
4523 String msg = "Permission Denial: startVoiceActivity() from pid="
4524 + Binder.getCallingPid()
4525 + ", uid=" + Binder.getCallingUid()
4526 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4528 throw new SecurityException(msg);
4530 if (session == null || interactor == null) {
4531 throw new NullPointerException("null session or interactor");
4533 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4534 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4535 // TODO: Switch to user app stacks here.
4536 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4537 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4538 null, bOptions, false, userId, null, null);
4542 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4543 throws RemoteException {
4544 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4545 synchronized (this) {
4546 ActivityRecord activity = getFocusedStack().topActivity();
4547 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4548 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4550 if (mRunningVoice != null || activity.task.voiceSession != null
4551 || activity.voiceSession != null) {
4552 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4555 if (activity.pendingVoiceInteractionStart) {
4556 Slog.w(TAG, "Pending start of voice interaction already.");
4559 activity.pendingVoiceInteractionStart = true;
4561 LocalServices.getService(VoiceInteractionManagerInternal.class)
4562 .startLocalVoiceInteraction(callingActivity, options);
4566 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4567 LocalServices.getService(VoiceInteractionManagerInternal.class)
4568 .stopLocalVoiceInteraction(callingActivity);
4572 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4573 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4574 .supportsLocalVoiceInteraction();
4577 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4578 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4579 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4580 if (activityToCallback == null) return;
4581 activityToCallback.setVoiceSessionLocked(voiceSession);
4583 // Inform the activity
4585 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4587 long token = Binder.clearCallingIdentity();
4589 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4591 Binder.restoreCallingIdentity(token);
4593 // TODO: VI Should we cache the activity so that it's easier to find later
4594 // rather than scan through all the stacks and activities?
4595 } catch (RemoteException re) {
4596 activityToCallback.clearVoiceSessionLocked();
4597 // TODO: VI Should this terminate the voice session?
4602 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4603 synchronized (this) {
4604 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4606 mVoiceWakeLock.acquire();
4608 mVoiceWakeLock.release();
4615 public boolean startNextMatchingActivity(IBinder callingActivity,
4616 Intent intent, Bundle bOptions) {
4617 // Refuse possible leaked file descriptors
4618 if (intent != null && intent.hasFileDescriptors() == true) {
4619 throw new IllegalArgumentException("File descriptors passed in Intent");
4621 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4623 synchronized (this) {
4624 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4626 ActivityOptions.abort(options);
4629 if (r.app == null || r.app.thread == null) {
4630 // The caller is not running... d'oh!
4631 ActivityOptions.abort(options);
4634 intent = new Intent(intent);
4635 // The caller is not allowed to change the data.
4636 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4637 // And we are resetting to find the next component...
4638 intent.setComponent(null);
4640 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4642 ActivityInfo aInfo = null;
4644 List<ResolveInfo> resolves =
4645 AppGlobals.getPackageManager().queryIntentActivities(
4646 intent, r.resolvedType,
4647 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4648 UserHandle.getCallingUserId()).getList();
4650 // Look for the original activity in the list...
4651 final int N = resolves != null ? resolves.size() : 0;
4652 for (int i=0; i<N; i++) {
4653 ResolveInfo rInfo = resolves.get(i);
4654 if (rInfo.activityInfo.packageName.equals(r.packageName)
4655 && rInfo.activityInfo.name.equals(r.info.name)) {
4656 // We found the current one... the next matching is
4660 aInfo = resolves.get(i).activityInfo;
4663 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4664 + "/" + r.info.name);
4665 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4666 ? "null" : aInfo.packageName + "/" + aInfo.name));
4671 } catch (RemoteException e) {
4674 if (aInfo == null) {
4675 // Nobody who is next!
4676 ActivityOptions.abort(options);
4677 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4681 intent.setComponent(new ComponentName(
4682 aInfo.applicationInfo.packageName, aInfo.name));
4683 intent.setFlags(intent.getFlags()&~(
4684 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4685 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4686 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4687 Intent.FLAG_ACTIVITY_NEW_TASK));
4689 // Okay now we need to start the new activity, replacing the
4690 // currently running activity. This is a little tricky because
4691 // we want to start the new one as if the current one is finished,
4692 // but not finish the current one first so that there is no flicker.
4694 final boolean wasFinishing = r.finishing;
4697 // Propagate reply information over to the new activity.
4698 final ActivityRecord resultTo = r.resultTo;
4699 final String resultWho = r.resultWho;
4700 final int requestCode = r.requestCode;
4702 if (resultTo != null) {
4703 resultTo.removeResultsLocked(r, resultWho, requestCode);
4706 final long origId = Binder.clearCallingIdentity();
4707 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4708 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4709 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4710 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4711 false, false, null, null, null);
4712 Binder.restoreCallingIdentity(origId);
4714 r.finishing = wasFinishing;
4715 if (res != ActivityManager.START_SUCCESS) {
4723 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4724 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4725 String msg = "Permission Denial: startActivityFromRecents called without " +
4726 START_TASKS_FROM_RECENTS;
4728 throw new SecurityException(msg);
4730 final long origId = Binder.clearCallingIdentity();
4732 synchronized (this) {
4733 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4736 Binder.restoreCallingIdentity(origId);
4740 final int startActivityInPackage(int uid, String callingPackage,
4741 Intent intent, String resolvedType, IBinder resultTo,
4742 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4743 IActivityContainer container, TaskRecord inTask) {
4745 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4746 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4748 // TODO: Switch to user app stacks here.
4749 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4750 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4751 null, null, null, bOptions, false, userId, container, inTask);
4756 public final int startActivities(IApplicationThread caller, String callingPackage,
4757 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4759 enforceNotIsolatedCaller("startActivities");
4760 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4761 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4762 // TODO: Switch to user app stacks here.
4763 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4764 resolvedTypes, resultTo, bOptions, userId);
4768 final int startActivitiesInPackage(int uid, String callingPackage,
4769 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4770 Bundle bOptions, int userId) {
4772 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4773 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4774 // TODO: Switch to user app stacks here.
4775 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4776 resultTo, bOptions, userId);
4781 public void reportActivityFullyDrawn(IBinder token) {
4782 synchronized (this) {
4783 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4787 r.reportFullyDrawnLocked();
4792 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4793 synchronized (this) {
4794 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4798 TaskRecord task = r.task;
4799 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4800 // Fixed screen orientation isn't supported when activities aren't in full screen
4804 final long origId = Binder.clearCallingIdentity();
4805 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4806 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4807 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4808 if (config != null) {
4809 r.frozenBeforeDestroy = true;
4810 if (!updateConfigurationLocked(config, r, false)) {
4811 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4814 Binder.restoreCallingIdentity(origId);
4819 public int getRequestedOrientation(IBinder token) {
4820 synchronized (this) {
4821 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4823 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4825 return mWindowManager.getAppOrientation(r.appToken);
4830 * This is the internal entry point for handling Activity.finish().
4832 * @param token The Binder token referencing the Activity we want to finish.
4833 * @param resultCode Result code, if any, from this Activity.
4834 * @param resultData Result data (Intent), if any, from this Activity.
4835 * @param finishTask Whether to finish the task associated with this Activity.
4837 * @return Returns true if the activity successfully finished, or false if it is still running.
4840 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4842 // Refuse possible leaked file descriptors
4843 if (resultData != null && resultData.hasFileDescriptors() == true) {
4844 throw new IllegalArgumentException("File descriptors passed in Intent");
4847 synchronized(this) {
4848 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4852 // Keep track of the root activity of the task before we finish it
4853 TaskRecord tr = r.task;
4854 ActivityRecord rootR = tr.getRootActivity();
4855 if (rootR == null) {
4856 Slog.w(TAG, "Finishing task with all activities already finished");
4858 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4860 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4861 mStackSupervisor.isLastLockedTask(tr)) {
4862 Slog.i(TAG, "Not finishing task in lock task mode");
4863 mStackSupervisor.showLockTaskToast();
4866 if (mController != null) {
4867 // Find the first activity that is not finishing.
4868 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4870 // ask watcher if this is allowed
4871 boolean resumeOK = true;
4873 resumeOK = mController.activityResuming(next.packageName);
4874 } catch (RemoteException e) {
4876 Watchdog.getInstance().setActivityController(null);
4880 Slog.i(TAG, "Not finishing activity because controller resumed");
4885 final long origId = Binder.clearCallingIdentity();
4888 final boolean finishWithRootActivity =
4889 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4890 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4891 || (finishWithRootActivity && r == rootR)) {
4892 // If requested, remove the task that is associated to this activity only if it
4893 // was the root activity in the task. The result code and data is ignored
4894 // because we don't support returning them across task boundaries. Also, to
4895 // keep backwards compatibility we remove the task from recents when finishing
4896 // task with root activity.
4897 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4899 Slog.i(TAG, "Removing task failed to finish activity");
4902 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4903 resultData, "app-request", true);
4905 Slog.i(TAG, "Failed to finish by app-request");
4910 Binder.restoreCallingIdentity(origId);
4916 public final void finishHeavyWeightApp() {
4917 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4918 != PackageManager.PERMISSION_GRANTED) {
4919 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4920 + Binder.getCallingPid()
4921 + ", uid=" + Binder.getCallingUid()
4922 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4924 throw new SecurityException(msg);
4927 synchronized(this) {
4928 if (mHeavyWeightProcess == null) {
4932 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4933 for (int i = 0; i < activities.size(); i++) {
4934 ActivityRecord r = activities.get(i);
4935 if (!r.finishing && r.isInStackLocked()) {
4936 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4937 null, "finish-heavy", true);
4941 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4942 mHeavyWeightProcess.userId, 0));
4943 mHeavyWeightProcess = null;
4948 public void crashApplication(int uid, int initialPid, String packageName,
4950 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4951 != PackageManager.PERMISSION_GRANTED) {
4952 String msg = "Permission Denial: crashApplication() from pid="
4953 + Binder.getCallingPid()
4954 + ", uid=" + Binder.getCallingUid()
4955 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4957 throw new SecurityException(msg);
4960 synchronized(this) {
4961 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4966 public final void finishSubActivity(IBinder token, String resultWho,
4968 synchronized(this) {
4969 final long origId = Binder.clearCallingIdentity();
4970 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4972 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4974 Binder.restoreCallingIdentity(origId);
4979 public boolean finishActivityAffinity(IBinder token) {
4980 synchronized(this) {
4981 final long origId = Binder.clearCallingIdentity();
4983 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4988 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4990 final TaskRecord task = r.task;
4991 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4992 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4993 mStackSupervisor.showLockTaskToast();
4996 return task.stack.finishActivityAffinityLocked(r);
4998 Binder.restoreCallingIdentity(origId);
5004 public void finishVoiceTask(IVoiceInteractionSession session) {
5005 synchronized (this) {
5006 final long origId = Binder.clearCallingIdentity();
5008 // TODO: VI Consider treating local voice interactions and voice tasks
5010 mStackSupervisor.finishVoiceTask(session);
5012 Binder.restoreCallingIdentity(origId);
5019 public boolean releaseActivityInstance(IBinder token) {
5020 synchronized(this) {
5021 final long origId = Binder.clearCallingIdentity();
5023 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5027 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5029 Binder.restoreCallingIdentity(origId);
5035 public void releaseSomeActivities(IApplicationThread appInt) {
5036 synchronized(this) {
5037 final long origId = Binder.clearCallingIdentity();
5039 ProcessRecord app = getRecordForAppLocked(appInt);
5040 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5042 Binder.restoreCallingIdentity(origId);
5048 public boolean willActivityBeVisible(IBinder token) {
5049 synchronized(this) {
5050 ActivityStack stack = ActivityRecord.getStackLocked(token);
5051 if (stack != null) {
5052 return stack.willActivityBeVisibleLocked(token);
5059 public void overridePendingTransition(IBinder token, String packageName,
5060 int enterAnim, int exitAnim) {
5061 synchronized(this) {
5062 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5067 final long origId = Binder.clearCallingIdentity();
5069 if (self.state == ActivityState.RESUMED
5070 || self.state == ActivityState.PAUSING) {
5071 mWindowManager.overridePendingAppTransition(packageName,
5072 enterAnim, exitAnim, null);
5075 Binder.restoreCallingIdentity(origId);
5080 * Main function for removing an existing process from the activity manager
5081 * as a result of that process going away. Clears out all connections
5084 private final void handleAppDiedLocked(ProcessRecord app,
5085 boolean restarting, boolean allowRestart) {
5087 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5088 false /*replacingPid*/);
5089 if (!kept && !restarting) {
5090 removeLruProcessLocked(app);
5092 ProcessList.remove(pid);
5096 if (mProfileProc == app) {
5097 clearProfilerLocked();
5100 // Remove this application's activities from active lists.
5101 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5103 app.activities.clear();
5105 if (app.instrumentationClass != null) {
5106 Slog.w(TAG, "Crash of app " + app.processName
5107 + " running instrumentation " + app.instrumentationClass);
5108 Bundle info = new Bundle();
5109 info.putString("shortMsg", "Process crashed.");
5110 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5113 if (!restarting && hasVisibleActivities
5114 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5115 // If there was nothing to resume, and we are not already restarting this process, but
5116 // there is a visible activity that is hosted by the process... then make sure all
5117 // visible activities are running, taking care of restarting this process.
5118 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5122 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5123 IBinder threadBinder = thread.asBinder();
5124 // Find the application record.
5125 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5126 ProcessRecord rec = mLruProcesses.get(i);
5127 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5134 final ProcessRecord getRecordForAppLocked(
5135 IApplicationThread thread) {
5136 if (thread == null) {
5140 int appIndex = getLRURecordIndexForAppLocked(thread);
5141 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5144 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5145 // If there are no longer any background processes running,
5146 // and the app that died was not running instrumentation,
5147 // then tell everyone we are now low on memory.
5148 boolean haveBg = false;
5149 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5150 ProcessRecord rec = mLruProcesses.get(i);
5151 if (rec.thread != null
5152 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5159 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5161 long now = SystemClock.uptimeMillis();
5162 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5165 mLastMemUsageReportTime = now;
5168 final ArrayList<ProcessMemInfo> memInfos
5169 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5170 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5171 long now = SystemClock.uptimeMillis();
5172 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5173 ProcessRecord rec = mLruProcesses.get(i);
5174 if (rec == dyingProc || rec.thread == null) {
5178 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5179 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5181 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5182 // The low memory report is overriding any current
5183 // state for a GC request. Make sure to do
5184 // heavy/important/visible/foreground processes first.
5185 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5186 rec.lastRequestedGc = 0;
5188 rec.lastRequestedGc = rec.lastLowMemory;
5190 rec.reportLowMemory = true;
5191 rec.lastLowMemory = now;
5192 mProcessesToGc.remove(rec);
5193 addProcessToGcListLocked(rec);
5197 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5198 mHandler.sendMessage(msg);
5200 scheduleAppGcsLocked();
5204 final void appDiedLocked(ProcessRecord app) {
5205 appDiedLocked(app, app.pid, app.thread, false);
5208 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5209 boolean fromBinderDied) {
5210 // First check if this ProcessRecord is actually active for the pid.
5211 synchronized (mPidsSelfLocked) {
5212 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5213 if (curProc != app) {
5214 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5219 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5220 synchronized (stats) {
5221 stats.noteProcessDiedLocked(app.info.uid, pid);
5225 if (!fromBinderDied) {
5226 Process.killProcessQuiet(pid);
5228 killProcessGroup(app.uid, pid);
5232 // Clean up already done if the process has been re-started.
5233 if (app.pid == pid && app.thread != null &&
5234 app.thread.asBinder() == thread.asBinder()) {
5235 boolean doLowMem = app.instrumentationClass == null;
5236 boolean doOomAdj = doLowMem;
5237 if (!app.killedByAm) {
5238 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5240 mAllowLowerMemLevel = true;
5242 // Note that we always want to do oom adj to update our state with the
5243 // new number of procs.
5244 mAllowLowerMemLevel = false;
5247 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5248 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5249 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5250 handleAppDiedLocked(app, false, true);
5253 updateOomAdjLocked();
5256 doLowMemReportIfNeededLocked(app);
5258 } else if (app.pid != pid) {
5259 // A new process has already been started.
5260 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5261 + ") has died and restarted (pid " + app.pid + ").");
5262 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5263 } else if (DEBUG_PROCESSES) {
5264 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5265 + thread.asBinder());
5270 * If a stack trace dump file is configured, dump process stack traces.
5271 * @param clearTraces causes the dump file to be erased prior to the new
5272 * traces being written, if true; when false, the new traces will be
5273 * appended to any existing file content.
5274 * @param firstPids of dalvik VM processes to dump stack traces for first
5275 * @param lastPids of dalvik VM processes to dump stack traces for last
5276 * @param nativeProcs optional list of native process names to dump stack crawls
5277 * @return file containing stack traces, or null if no dump file is configured
5279 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5280 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5281 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5282 if (tracesPath == null || tracesPath.length() == 0) {
5286 File tracesFile = new File(tracesPath);
5288 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5289 tracesFile.createNewFile();
5290 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5291 } catch (IOException e) {
5292 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5296 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5300 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5301 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5302 // Use a FileObserver to detect when traces finish writing.
5303 // The order of traces is considered important to maintain for legibility.
5304 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5306 public synchronized void onEvent(int event, String path) { notify(); }
5310 observer.startWatching();
5312 // First collect all of the stacks of the most important pids.
5313 if (firstPids != null) {
5315 int num = firstPids.size();
5316 for (int i = 0; i < num; i++) {
5317 synchronized (observer) {
5318 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5319 + firstPids.get(i));
5320 final long sime = SystemClock.elapsedRealtime();
5321 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5322 observer.wait(1000); // Wait for write-close, give up after 1 sec
5323 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5324 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5327 } catch (InterruptedException e) {
5332 // Next collect the stacks of the native pids
5333 if (nativeProcs != null) {
5334 int[] pids = Process.getPidsForCommands(nativeProcs);
5336 for (int pid : pids) {
5337 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5338 final long sime = SystemClock.elapsedRealtime();
5339 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5340 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5341 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5346 // Lastly, measure CPU usage.
5347 if (processCpuTracker != null) {
5348 processCpuTracker.init();
5350 processCpuTracker.update();
5352 synchronized (processCpuTracker) {
5353 processCpuTracker.wait(500); // measure over 1/2 second.
5355 } catch (InterruptedException e) {
5357 processCpuTracker.update();
5359 // We'll take the stack crawls of just the top apps using CPU.
5360 final int N = processCpuTracker.countWorkingStats();
5362 for (int i=0; i<N && numProcs<5; i++) {
5363 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5364 if (lastPids.indexOfKey(stats.pid) >= 0) {
5367 synchronized (observer) {
5368 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5370 final long stime = SystemClock.elapsedRealtime();
5371 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5372 observer.wait(1000); // Wait for write-close, give up after 1 sec
5373 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5374 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5376 } catch (InterruptedException e) {
5379 } else if (DEBUG_ANR) {
5380 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5386 observer.stopWatching();
5390 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5391 if (true || IS_USER_BUILD) {
5394 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5395 if (tracesPath == null || tracesPath.length() == 0) {
5399 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5400 StrictMode.allowThreadDiskWrites();
5402 final File tracesFile = new File(tracesPath);
5403 final File tracesDir = tracesFile.getParentFile();
5404 final File tracesTmp = new File(tracesDir, "__tmp__");
5406 if (tracesFile.exists()) {
5408 tracesFile.renameTo(tracesTmp);
5410 StringBuilder sb = new StringBuilder();
5411 Time tobj = new Time();
5412 tobj.set(System.currentTimeMillis());
5413 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5415 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5416 sb.append(" since ");
5418 FileOutputStream fos = new FileOutputStream(tracesFile);
5419 fos.write(sb.toString().getBytes());
5421 fos.write("\n*** No application process!".getBytes());
5424 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5425 } catch (IOException e) {
5426 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5431 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5432 firstPids.add(app.pid);
5433 dumpStackTraces(tracesPath, firstPids, null, null, null);
5436 File lastTracesFile = null;
5437 File curTracesFile = null;
5438 for (int i=9; i>=0; i--) {
5439 String name = String.format(Locale.US, "slow%02d.txt", i);
5440 curTracesFile = new File(tracesDir, name);
5441 if (curTracesFile.exists()) {
5442 if (lastTracesFile != null) {
5443 curTracesFile.renameTo(lastTracesFile);
5445 curTracesFile.delete();
5448 lastTracesFile = curTracesFile;
5450 tracesFile.renameTo(curTracesFile);
5451 if (tracesTmp.exists()) {
5452 tracesTmp.renameTo(tracesFile);
5455 StrictMode.setThreadPolicy(oldPolicy);
5459 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5460 if (!mLaunchWarningShown) {
5461 mLaunchWarningShown = true;
5462 mUiHandler.post(new Runnable() {
5465 synchronized (ActivityManagerService.this) {
5466 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5468 mUiHandler.postDelayed(new Runnable() {
5471 synchronized (ActivityManagerService.this) {
5473 mLaunchWarningShown = false;
5484 public boolean clearApplicationUserData(final String packageName,
5485 final IPackageDataObserver observer, int userId) {
5486 enforceNotIsolatedCaller("clearApplicationUserData");
5487 int uid = Binder.getCallingUid();
5488 int pid = Binder.getCallingPid();
5489 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5490 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5493 long callingId = Binder.clearCallingIdentity();
5495 IPackageManager pm = AppGlobals.getPackageManager();
5497 synchronized(this) {
5498 if (getPackageManagerInternalLocked().isPackageDataProtected(
5499 userId, packageName)) {
5500 throw new SecurityException(
5501 "Cannot clear data for a protected package: " + packageName);
5505 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5506 } catch (RemoteException e) {
5509 Slog.w(TAG, "Invalid packageName: " + packageName);
5510 if (observer != null) {
5512 observer.onRemoveCompleted(packageName, false);
5513 } catch (RemoteException e) {
5514 Slog.i(TAG, "Observer no longer exists.");
5519 if (uid == pkgUid || checkComponentPermission(
5520 android.Manifest.permission.CLEAR_APP_USER_DATA,
5522 == PackageManager.PERMISSION_GRANTED) {
5523 forceStopPackageLocked(packageName, pkgUid, "clear data");
5525 throw new SecurityException("PID " + pid + " does not have permission "
5526 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5527 + " of package " + packageName);
5530 // Remove all tasks match the cleared application package and user
5531 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5532 final TaskRecord tr = mRecentTasks.get(i);
5533 final String taskPackageName =
5534 tr.getBaseIntent().getComponent().getPackageName();
5535 if (tr.userId != userId) continue;
5536 if (!taskPackageName.equals(packageName)) continue;
5537 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5541 final int pkgUidF = pkgUid;
5542 final int userIdF = userId;
5543 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5545 public void onRemoveCompleted(String packageName, boolean succeeded)
5546 throws RemoteException {
5547 synchronized (ActivityManagerService.this) {
5548 finishForceStopPackageLocked(packageName, pkgUidF);
5551 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5552 Uri.fromParts("package", packageName, null));
5553 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5554 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5555 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5556 null, null, 0, null, null, null, null, false, false, userIdF);
5558 if (observer != null) {
5559 observer.onRemoveCompleted(packageName, succeeded);
5565 // Clear application user data
5566 pm.clearApplicationUserData(packageName, localObserver, userId);
5568 synchronized(this) {
5569 // Remove all permissions granted from/to this package
5570 removeUriPermissionsForPackageLocked(packageName, userId, true);
5573 // Remove all zen rules created by this package; revoke it's zen access.
5574 INotificationManager inm = NotificationManager.getService();
5575 inm.removeAutomaticZenRules(packageName);
5576 inm.setNotificationPolicyAccessGranted(packageName, false);
5578 } catch (RemoteException e) {
5581 Binder.restoreCallingIdentity(callingId);
5587 public void killBackgroundProcesses(final String packageName, int userId) {
5588 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5589 != PackageManager.PERMISSION_GRANTED &&
5590 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5591 != PackageManager.PERMISSION_GRANTED) {
5592 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5593 + Binder.getCallingPid()
5594 + ", uid=" + Binder.getCallingUid()
5595 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5597 throw new SecurityException(msg);
5600 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5601 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5602 long callingId = Binder.clearCallingIdentity();
5604 IPackageManager pm = AppGlobals.getPackageManager();
5605 synchronized(this) {
5608 appId = UserHandle.getAppId(
5609 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5610 } catch (RemoteException e) {
5613 Slog.w(TAG, "Invalid packageName: " + packageName);
5616 killPackageProcessesLocked(packageName, appId, userId,
5617 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5620 Binder.restoreCallingIdentity(callingId);
5625 public void killAllBackgroundProcesses() {
5626 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5627 != PackageManager.PERMISSION_GRANTED) {
5628 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5629 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5630 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5632 throw new SecurityException(msg);
5635 final long callingId = Binder.clearCallingIdentity();
5637 synchronized (this) {
5638 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5639 final int NP = mProcessNames.getMap().size();
5640 for (int ip = 0; ip < NP; ip++) {
5641 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5642 final int NA = apps.size();
5643 for (int ia = 0; ia < NA; ia++) {
5644 final ProcessRecord app = apps.valueAt(ia);
5645 if (app.persistent) {
5646 // We don't kill persistent processes.
5651 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5658 final int N = procs.size();
5659 for (int i = 0; i < N; i++) {
5660 removeProcessLocked(procs.get(i), false, true, "kill all background");
5663 mAllowLowerMemLevel = true;
5665 updateOomAdjLocked();
5666 doLowMemReportIfNeededLocked(null);
5669 Binder.restoreCallingIdentity(callingId);
5674 * Kills all background processes, except those matching any of the
5675 * specified properties.
5677 * @param minTargetSdk the target SDK version at or above which to preserve
5678 * processes, or {@code -1} to ignore the target SDK
5679 * @param maxProcState the process state at or below which to preserve
5680 * processes, or {@code -1} to ignore the process state
5682 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5683 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5684 != PackageManager.PERMISSION_GRANTED) {
5685 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5686 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5687 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5689 throw new SecurityException(msg);
5692 final long callingId = Binder.clearCallingIdentity();
5694 synchronized (this) {
5695 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5696 final int NP = mProcessNames.getMap().size();
5697 for (int ip = 0; ip < NP; ip++) {
5698 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5699 final int NA = apps.size();
5700 for (int ia = 0; ia < NA; ia++) {
5701 final ProcessRecord app = apps.valueAt(ia);
5704 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5705 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5712 final int N = procs.size();
5713 for (int i = 0; i < N; i++) {
5714 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5718 Binder.restoreCallingIdentity(callingId);
5723 public void forceStopPackage(final String packageName, int userId) {
5724 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5725 != PackageManager.PERMISSION_GRANTED) {
5726 String msg = "Permission Denial: forceStopPackage() from pid="
5727 + Binder.getCallingPid()
5728 + ", uid=" + Binder.getCallingUid()
5729 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5731 throw new SecurityException(msg);
5733 final int callingPid = Binder.getCallingPid();
5734 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5735 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5736 long callingId = Binder.clearCallingIdentity();
5738 IPackageManager pm = AppGlobals.getPackageManager();
5739 synchronized(this) {
5740 int[] users = userId == UserHandle.USER_ALL
5741 ? mUserController.getUsers() : new int[] { userId };
5742 for (int user : users) {
5745 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5747 } catch (RemoteException e) {
5750 Slog.w(TAG, "Invalid packageName: " + packageName);
5754 pm.setPackageStoppedState(packageName, true, user);
5755 } catch (RemoteException e) {
5756 } catch (IllegalArgumentException e) {
5757 Slog.w(TAG, "Failed trying to unstop package "
5758 + packageName + ": " + e);
5760 if (mUserController.isUserRunningLocked(user, 0)) {
5761 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5762 finishForceStopPackageLocked(packageName, pkgUid);
5767 Binder.restoreCallingIdentity(callingId);
5772 public void addPackageDependency(String packageName) {
5773 synchronized (this) {
5774 int callingPid = Binder.getCallingPid();
5775 if (callingPid == Process.myPid()) {
5780 synchronized (mPidsSelfLocked) {
5781 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5784 if (proc.pkgDeps == null) {
5785 proc.pkgDeps = new ArraySet<String>(1);
5787 proc.pkgDeps.add(packageName);
5793 * The pkg name and app id have to be specified.
5796 public void killApplication(String pkg, int appId, int userId, String reason) {
5800 // Make sure the uid is valid.
5802 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5805 int callerUid = Binder.getCallingUid();
5806 // Only the system server can kill an application
5807 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5808 // Post an aysnc message to kill the application
5809 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5812 Bundle bundle = new Bundle();
5813 bundle.putString("pkg", pkg);
5814 bundle.putString("reason", reason);
5816 mHandler.sendMessage(msg);
5818 throw new SecurityException(callerUid + " cannot kill pkg: " +
5824 public void closeSystemDialogs(String reason) {
5825 enforceNotIsolatedCaller("closeSystemDialogs");
5827 final int pid = Binder.getCallingPid();
5828 final int uid = Binder.getCallingUid();
5829 final long origId = Binder.clearCallingIdentity();
5831 synchronized (this) {
5832 // Only allow this from foreground processes, so that background
5833 // applications can't abuse it to prevent system UI from being shown.
5834 if (uid >= Process.FIRST_APPLICATION_UID) {
5836 synchronized (mPidsSelfLocked) {
5837 proc = mPidsSelfLocked.get(pid);
5839 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5840 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5841 + " from background process " + proc);
5845 closeSystemDialogsLocked(reason);
5848 Binder.restoreCallingIdentity(origId);
5852 void closeSystemDialogsLocked(String reason) {
5853 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5854 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5855 | Intent.FLAG_RECEIVER_FOREGROUND);
5856 if (reason != null) {
5857 intent.putExtra("reason", reason);
5859 mWindowManager.closeSystemDialogs(reason);
5861 mStackSupervisor.closeSystemDialogsLocked();
5863 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5864 AppOpsManager.OP_NONE, null, false, false,
5865 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5869 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5870 enforceNotIsolatedCaller("getProcessMemoryInfo");
5871 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5872 for (int i=pids.length-1; i>=0; i--) {
5875 synchronized (this) {
5876 synchronized (mPidsSelfLocked) {
5877 proc = mPidsSelfLocked.get(pids[i]);
5878 oomAdj = proc != null ? proc.setAdj : 0;
5881 infos[i] = new Debug.MemoryInfo();
5882 Debug.getMemoryInfo(pids[i], infos[i]);
5884 synchronized (this) {
5885 if (proc.thread != null && proc.setAdj == oomAdj) {
5886 // Record this for posterity if the process has been stable.
5887 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5888 infos[i].getTotalUss(), false, proc.pkgList);
5897 public long[] getProcessPss(int[] pids) {
5898 enforceNotIsolatedCaller("getProcessPss");
5899 long[] pss = new long[pids.length];
5900 for (int i=pids.length-1; i>=0; i--) {
5903 synchronized (this) {
5904 synchronized (mPidsSelfLocked) {
5905 proc = mPidsSelfLocked.get(pids[i]);
5906 oomAdj = proc != null ? proc.setAdj : 0;
5909 long[] tmpUss = new long[1];
5910 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5912 synchronized (this) {
5913 if (proc.thread != null && proc.setAdj == oomAdj) {
5914 // Record this for posterity if the process has been stable.
5915 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5924 public void killApplicationProcess(String processName, int uid) {
5925 if (processName == null) {
5929 int callerUid = Binder.getCallingUid();
5930 // Only the system server can kill an application
5931 if (callerUid == Process.SYSTEM_UID) {
5932 synchronized (this) {
5933 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5934 if (app != null && app.thread != null) {
5936 app.thread.scheduleSuicide();
5937 } catch (RemoteException e) {
5938 // If the other end already died, then our work here is done.
5941 Slog.w(TAG, "Process/uid not found attempting kill of "
5942 + processName + " / " + uid);
5946 throw new SecurityException(callerUid + " cannot kill app process: " +
5951 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5952 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5953 false, true, false, false, UserHandle.getUserId(uid), reason);
5956 private void finishForceStopPackageLocked(final String packageName, int uid) {
5957 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5958 Uri.fromParts("package", packageName, null));
5959 if (!mProcessesReady) {
5960 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5961 | Intent.FLAG_RECEIVER_FOREGROUND);
5963 intent.putExtra(Intent.EXTRA_UID, uid);
5964 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5965 broadcastIntentLocked(null, null, intent,
5966 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5967 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5971 private final boolean killPackageProcessesLocked(String packageName, int appId,
5972 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5973 boolean doit, boolean evenPersistent, String reason) {
5974 ArrayList<ProcessRecord> procs = new ArrayList<>();
5976 // Remove all processes this package may have touched: all with the
5977 // same UID (except for the system or root user), and all whose name
5978 // matches the package name.
5979 final int NP = mProcessNames.getMap().size();
5980 for (int ip=0; ip<NP; ip++) {
5981 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5982 final int NA = apps.size();
5983 for (int ia=0; ia<NA; ia++) {
5984 ProcessRecord app = apps.valueAt(ia);
5985 if (app.persistent && !evenPersistent) {
5986 // we don't kill persistent processes
5996 // Skip process if it doesn't meet our oom adj requirement.
5997 if (app.setAdj < minOomAdj) {
6001 // If no package is specified, we call all processes under the
6003 if (packageName == null) {
6004 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6007 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6010 // Package has been specified, we want to hit all processes
6011 // that match it. We need to qualify this by the processes
6012 // that are running under the specified app and user ID.
6014 final boolean isDep = app.pkgDeps != null
6015 && app.pkgDeps.contains(packageName);
6016 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6019 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6022 if (!app.pkgList.containsKey(packageName) && !isDep) {
6027 // Process has passed all conditions, kill it!
6036 int N = procs.size();
6037 for (int i=0; i<N; i++) {
6038 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6040 updateOomAdjLocked();
6044 private void cleanupDisabledPackageComponentsLocked(
6045 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6047 Set<String> disabledClasses = null;
6048 boolean packageDisabled = false;
6049 IPackageManager pm = AppGlobals.getPackageManager();
6051 if (changedClasses == null) {
6052 // Nothing changed...
6056 // Determine enable/disable state of the package and its components.
6057 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6058 for (int i = changedClasses.length - 1; i >= 0; i--) {
6059 final String changedClass = changedClasses[i];
6061 if (changedClass.equals(packageName)) {
6063 // Entire package setting changed
6064 enabled = pm.getApplicationEnabledSetting(packageName,
6065 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6066 } catch (Exception e) {
6067 // No such package/component; probably racing with uninstall. In any
6068 // event it means we have nothing further to do here.
6071 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6072 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6073 if (packageDisabled) {
6074 // Entire package is disabled.
6075 // No need to continue to check component states.
6076 disabledClasses = null;
6081 enabled = pm.getComponentEnabledSetting(
6082 new ComponentName(packageName, changedClass),
6083 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6084 } catch (Exception e) {
6085 // As above, probably racing with uninstall.
6088 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6089 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6090 if (disabledClasses == null) {
6091 disabledClasses = new ArraySet<>(changedClasses.length);
6093 disabledClasses.add(changedClass);
6098 if (!packageDisabled && disabledClasses == null) {
6099 // Nothing to do here...
6103 // Clean-up disabled activities.
6104 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6105 packageName, disabledClasses, true, false, userId) && mBooted) {
6106 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6107 mStackSupervisor.scheduleIdleLocked();
6110 // Clean-up disabled tasks
6111 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6113 // Clean-up disabled services.
6114 mServices.bringDownDisabledPackageServicesLocked(
6115 packageName, disabledClasses, userId, false, killProcess, true);
6117 // Clean-up disabled providers.
6118 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6119 mProviderMap.collectPackageProvidersLocked(
6120 packageName, disabledClasses, true, false, userId, providers);
6121 for (int i = providers.size() - 1; i >= 0; i--) {
6122 removeDyingProviderLocked(null, providers.get(i), true);
6125 // Clean-up disabled broadcast receivers.
6126 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6127 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6128 packageName, disabledClasses, userId, true);
6133 final boolean clearBroadcastQueueForUserLocked(int userId) {
6134 boolean didSomething = false;
6135 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6136 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6137 null, null, userId, true);
6139 return didSomething;
6142 final boolean forceStopPackageLocked(String packageName, int appId,
6143 boolean callerWillRestart, boolean purgeCache, boolean doit,
6144 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6147 if (userId == UserHandle.USER_ALL && packageName == null) {
6148 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6151 if (appId < 0 && packageName != null) {
6153 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6154 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6155 } catch (RemoteException e) {
6160 if (packageName != null) {
6161 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6162 + " user=" + userId + ": " + reason);
6164 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6167 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6170 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6171 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6172 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6174 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6175 packageName, null, doit, evenPersistent, userId)) {
6179 didSomething = true;
6182 if (mServices.bringDownDisabledPackageServicesLocked(
6183 packageName, null, userId, evenPersistent, true, doit)) {
6187 didSomething = true;
6190 if (packageName == null) {
6191 // Remove all sticky broadcasts from this user.
6192 mStickyBroadcasts.remove(userId);
6195 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6196 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6197 userId, providers)) {
6201 didSomething = true;
6203 for (i = providers.size() - 1; i >= 0; i--) {
6204 removeDyingProviderLocked(null, providers.get(i), true);
6207 // Remove transient permissions granted from/to this package/user
6208 removeUriPermissionsForPackageLocked(packageName, userId, false);
6211 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6212 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6213 packageName, null, userId, doit);
6217 if (packageName == null || uninstalling) {
6218 // Remove pending intents. For now we only do this when force
6219 // stopping users, because we have some problems when doing this
6220 // for packages -- app widgets are not currently cleaned up for
6221 // such packages, so they can be left with bad pending intents.
6222 if (mIntentSenderRecords.size() > 0) {
6223 Iterator<WeakReference<PendingIntentRecord>> it
6224 = mIntentSenderRecords.values().iterator();
6225 while (it.hasNext()) {
6226 WeakReference<PendingIntentRecord> wpir = it.next();
6231 PendingIntentRecord pir = wpir.get();
6236 if (packageName == null) {
6237 // Stopping user, remove all objects for the user.
6238 if (pir.key.userId != userId) {
6239 // Not the same user, skip it.
6243 if (UserHandle.getAppId(pir.uid) != appId) {
6244 // Different app id, skip it.
6247 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6248 // Different user, skip it.
6251 if (!pir.key.packageName.equals(packageName)) {
6252 // Different package, skip it.
6259 didSomething = true;
6261 pir.canceled = true;
6262 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6263 pir.key.activity.pendingResults.remove(pir.ref);
6270 if (purgeCache && packageName != null) {
6271 AttributeCache ac = AttributeCache.instance();
6273 ac.removePackage(packageName);
6277 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6278 mStackSupervisor.scheduleIdleLocked();
6282 return didSomething;
6285 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6286 return removeProcessNameLocked(name, uid, null);
6289 private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6290 final ProcessRecord expecting) {
6291 ProcessRecord old = mProcessNames.get(name, uid);
6292 // Only actually remove when the currently recorded value matches the
6293 // record that we expected; if it doesn't match then we raced with a
6294 // newly created process and we don't want to destroy the new one.
6295 if ((expecting == null) || (old == expecting)) {
6296 mProcessNames.remove(name, uid);
6298 if (old != null && old.uidRecord != null) {
6299 old.uidRecord.numProcs--;
6300 if (old.uidRecord.numProcs == 0) {
6301 // No more processes using this uid, tell clients it is gone.
6302 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6303 "No more processes in " + old.uidRecord);
6304 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6305 mActiveUids.remove(uid);
6306 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6308 old.uidRecord = null;
6310 mIsolatedProcesses.remove(uid);
6314 private final void addProcessNameLocked(ProcessRecord proc) {
6315 // We shouldn't already have a process under this name, but just in case we
6316 // need to clean up whatever may be there now.
6317 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6318 if (old == proc && proc.persistent) {
6319 // We are re-adding a persistent process. Whatevs! Just leave it there.
6320 Slog.w(TAG, "Re-adding persistent process " + proc);
6321 } else if (old != null) {
6322 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6324 UidRecord uidRec = mActiveUids.get(proc.uid);
6325 if (uidRec == null) {
6326 uidRec = new UidRecord(proc.uid);
6327 // This is the first appearance of the uid, report it now!
6328 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6329 "Creating new process uid: " + uidRec);
6330 mActiveUids.put(proc.uid, uidRec);
6331 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6332 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6334 proc.uidRecord = uidRec;
6336 // Reset render thread tid if it was already set, so new process can set it again.
6337 proc.renderThreadTid = 0;
6339 mProcessNames.put(proc.processName, proc.uid, proc);
6340 if (proc.isolated) {
6341 mIsolatedProcesses.put(proc.uid, proc);
6345 boolean removeProcessLocked(ProcessRecord app,
6346 boolean callerWillRestart, boolean allowRestart, String reason) {
6347 final String name = app.processName;
6348 final int uid = app.uid;
6349 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6350 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6352 ProcessRecord old = mProcessNames.get(name, uid);
6354 // This process is no longer active, so nothing to do.
6355 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6358 removeProcessNameLocked(name, uid);
6359 if (mHeavyWeightProcess == app) {
6360 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6361 mHeavyWeightProcess.userId, 0));
6362 mHeavyWeightProcess = null;
6364 boolean needRestart = false;
6365 if (app.pid > 0 && app.pid != MY_PID) {
6367 synchronized (mPidsSelfLocked) {
6368 mPidsSelfLocked.remove(pid);
6369 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6371 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6373 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6375 boolean willRestart = false;
6376 if (app.persistent && !app.isolated) {
6377 if (!callerWillRestart) {
6383 app.kill(reason, true);
6384 handleAppDiedLocked(app, willRestart, allowRestart);
6386 removeLruProcessLocked(app);
6387 addAppLocked(app.info, false, null /* ABI override */);
6390 mRemovedProcesses.add(app);
6396 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6397 cleanupAppInLaunchingProvidersLocked(app, true);
6398 removeProcessLocked(app, false, true, "timeout publishing content providers");
6401 private final void processStartTimedOutLocked(ProcessRecord app) {
6402 final int pid = app.pid;
6403 boolean gone = false;
6404 synchronized (mPidsSelfLocked) {
6405 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6406 if (knownApp != null && knownApp.thread == null) {
6407 mPidsSelfLocked.remove(pid);
6413 Slog.w(TAG, "Process " + app + " failed to attach");
6414 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6415 pid, app.uid, app.processName);
6416 removeProcessNameLocked(app.processName, app.uid);
6417 if (mHeavyWeightProcess == app) {
6418 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6419 mHeavyWeightProcess.userId, 0));
6420 mHeavyWeightProcess = null;
6422 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6424 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6426 // Take care of any launching providers waiting for this process.
6427 cleanupAppInLaunchingProvidersLocked(app, true);
6428 // Take care of any services that are waiting for the process.
6429 mServices.processStartTimedOutLocked(app);
6430 app.kill("start timeout", true);
6431 removeLruProcessLocked(app);
6432 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6433 Slog.w(TAG, "Unattached app died before backup, skipping");
6435 IBackupManager bm = IBackupManager.Stub.asInterface(
6436 ServiceManager.getService(Context.BACKUP_SERVICE));
6437 bm.agentDisconnected(app.info.packageName);
6438 } catch (RemoteException e) {
6439 // Can't happen; the backup manager is local
6442 if (isPendingBroadcastProcessLocked(pid)) {
6443 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6444 skipPendingBroadcastLocked(pid);
6447 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6451 private final boolean attachApplicationLocked(IApplicationThread thread,
6454 // Find the application record that is being attached... either via
6455 // the pid if we are running in multiple processes, or just pull the
6456 // next app record if we are emulating process with anonymous threads.
6458 if (pid != MY_PID && pid >= 0) {
6459 synchronized (mPidsSelfLocked) {
6460 app = mPidsSelfLocked.get(pid);
6467 Slog.w(TAG, "No pending application record for pid " + pid
6468 + " (IApplicationThread " + thread + "); dropping process");
6469 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6470 if (pid > 0 && pid != MY_PID) {
6471 Process.killProcessQuiet(pid);
6472 //TODO: killProcessGroup(app.info.uid, pid);
6475 thread.scheduleExit();
6476 } catch (Exception e) {
6477 // Ignore exceptions.
6483 // If this application record is still attached to a previous
6484 // process, clean it up now.
6485 if (app.thread != null) {
6486 handleAppDiedLocked(app, true, true);
6489 // Tell the process all about itself.
6491 if (DEBUG_ALL) Slog.v(
6492 TAG, "Binding process pid " + pid + " to record " + app);
6494 final String processName = app.processName;
6496 AppDeathRecipient adr = new AppDeathRecipient(
6498 thread.asBinder().linkToDeath(adr, 0);
6499 app.deathRecipient = adr;
6500 } catch (RemoteException e) {
6501 app.resetPackageList(mProcessStats);
6502 startProcessLocked(app, "link fail", processName);
6506 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6508 app.makeActive(thread, mProcessStats);
6509 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6510 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6511 app.forcingToForeground = null;
6512 updateProcessForegroundLocked(app, false, false);
6513 app.hasShownUi = false;
6514 app.debugging = false;
6516 app.killedByAm = false;
6518 // We carefully use the same state that PackageManager uses for
6519 // filtering, since we use this flag to decide if we need to install
6520 // providers when user is unlocked later
6521 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6523 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6525 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6526 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6528 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6529 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6531 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6535 Slog.i(TAG, "Launching preboot mode app: " + app);
6538 if (DEBUG_ALL) Slog.v(
6539 TAG, "New app record " + app
6540 + " thread=" + thread.asBinder() + " pid=" + pid);
6542 int testMode = IApplicationThread.DEBUG_OFF;
6543 if (mDebugApp != null && mDebugApp.equals(processName)) {
6544 testMode = mWaitForDebugger
6545 ? IApplicationThread.DEBUG_WAIT
6546 : IApplicationThread.DEBUG_ON;
6547 app.debugging = true;
6548 if (mDebugTransient) {
6549 mDebugApp = mOrigDebugApp;
6550 mWaitForDebugger = mOrigWaitForDebugger;
6553 String profileFile = app.instrumentationProfileFile;
6554 ParcelFileDescriptor profileFd = null;
6555 int samplingInterval = 0;
6556 boolean profileAutoStop = false;
6557 if (mProfileApp != null && mProfileApp.equals(processName)) {
6559 profileFile = mProfileFile;
6560 profileFd = mProfileFd;
6561 samplingInterval = mSamplingInterval;
6562 profileAutoStop = mAutoStopProfiler;
6564 boolean enableTrackAllocation = false;
6565 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6566 enableTrackAllocation = true;
6567 mTrackAllocationApp = null;
6570 // If the app is being launched for restore or full backup, set it up specially
6571 boolean isRestrictedBackupMode = false;
6572 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6573 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6574 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6575 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6576 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6579 if (app.instrumentationClass != null) {
6580 notifyPackageUse(app.instrumentationClass.getPackageName(),
6581 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6583 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6584 + processName + " with config " + mConfiguration);
6585 ApplicationInfo appInfo = app.instrumentationInfo != null
6586 ? app.instrumentationInfo : app.info;
6587 app.compat = compatibilityInfoForPackageLocked(appInfo);
6588 if (profileFd != null) {
6589 profileFd = profileFd.dup();
6591 ProfilerInfo profilerInfo = profileFile == null ? null
6592 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6593 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6594 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6595 app.instrumentationUiAutomationConnection, testMode,
6596 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6597 isRestrictedBackupMode || !normalMode, app.persistent,
6598 new Configuration(mConfiguration), app.compat,
6599 getCommonServicesLocked(app.isolated),
6600 mCoreSettingsObserver.getCoreSettingsLocked());
6601 updateLruProcessLocked(app, false, null);
6602 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6603 } catch (Exception e) {
6604 // todo: Yikes! What should we do? For now we will try to
6605 // start another process, but that could easily get us in
6606 // an infinite loop of restarting processes...
6607 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6609 app.resetPackageList(mProcessStats);
6610 app.unlinkDeathRecipient();
6611 startProcessLocked(app, "bind fail", processName);
6615 // Remove this record from the list of starting applications.
6616 mPersistentStartingProcesses.remove(app);
6617 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6618 "Attach application locked removing on hold: " + app);
6619 mProcessesOnHold.remove(app);
6621 boolean badApp = false;
6622 boolean didSomething = false;
6624 // See if the top visible activity is waiting to run in this process...
6627 if (mStackSupervisor.attachApplicationLocked(app)) {
6628 didSomething = true;
6630 } catch (Exception e) {
6631 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6636 // Find any services that should be running in this process...
6639 didSomething |= mServices.attachApplicationLocked(app, processName);
6640 } catch (Exception e) {
6641 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6646 // Check if a next-broadcast receiver is in this process...
6647 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6649 didSomething |= sendPendingBroadcastsLocked(app);
6650 } catch (Exception e) {
6651 // If the app died trying to launch the receiver we declare it 'bad'
6652 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6657 // Check whether the next backup agent is in this process...
6658 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6659 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6660 "New app is backup target, launching agent for " + app);
6661 notifyPackageUse(mBackupTarget.appInfo.packageName,
6662 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6664 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6665 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6666 mBackupTarget.backupMode);
6667 } catch (Exception e) {
6668 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6674 app.kill("error during init", true);
6675 handleAppDiedLocked(app, false, true);
6679 if (!didSomething) {
6680 updateOomAdjLocked();
6687 public final void attachApplication(IApplicationThread thread) {
6688 synchronized (this) {
6689 int callingPid = Binder.getCallingPid();
6690 final long origId = Binder.clearCallingIdentity();
6691 attachApplicationLocked(thread, callingPid);
6692 Binder.restoreCallingIdentity(origId);
6697 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6698 final long origId = Binder.clearCallingIdentity();
6699 synchronized (this) {
6700 ActivityStack stack = ActivityRecord.getStackLocked(token);
6701 if (stack != null) {
6703 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6704 if (stopProfiling) {
6705 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6708 } catch (IOException e) {
6710 clearProfilerLocked();
6715 Binder.restoreCallingIdentity(origId);
6718 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6719 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6720 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6723 void enableScreenAfterBoot() {
6724 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6725 SystemClock.uptimeMillis());
6726 mWindowManager.enableScreenAfterBoot();
6728 synchronized (this) {
6729 updateEventDispatchingLocked();
6734 public void showBootMessage(final CharSequence msg, final boolean always) {
6735 if (Binder.getCallingUid() != Process.myUid()) {
6736 throw new SecurityException();
6738 mWindowManager.showBootMessage(msg, always);
6742 public void keyguardWaitingForActivityDrawn() {
6743 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6744 final long token = Binder.clearCallingIdentity();
6746 synchronized (this) {
6747 if (DEBUG_LOCKSCREEN) logLockScreen("");
6748 mWindowManager.keyguardWaitingForActivityDrawn();
6749 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6750 mLockScreenShown = LOCK_SCREEN_LEAVING;
6751 updateSleepIfNeededLocked();
6755 Binder.restoreCallingIdentity(token);
6760 public void keyguardGoingAway(int flags) {
6761 enforceNotIsolatedCaller("keyguardGoingAway");
6762 final long token = Binder.clearCallingIdentity();
6764 synchronized (this) {
6765 if (DEBUG_LOCKSCREEN) logLockScreen("");
6766 mWindowManager.keyguardGoingAway(flags);
6767 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6768 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6769 updateSleepIfNeededLocked();
6771 // Some stack visibility might change (e.g. docked stack)
6772 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6773 applyVrModeIfNeededLocked(mFocusedActivity, true);
6777 Binder.restoreCallingIdentity(token);
6781 final void finishBooting() {
6782 synchronized (this) {
6783 if (!mBootAnimationComplete) {
6784 mCallFinishBooting = true;
6787 mCallFinishBooting = false;
6790 ArraySet<String> completedIsas = new ArraySet<String>();
6791 for (String abi : Build.SUPPORTED_ABIS) {
6792 Process.establishZygoteConnectionForAbi(abi);
6793 final String instructionSet = VMRuntime.getInstructionSet(abi);
6794 if (!completedIsas.contains(instructionSet)) {
6796 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6797 } catch (InstallerException e) {
6798 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6799 e.getMessage() +")");
6801 completedIsas.add(instructionSet);
6805 IntentFilter pkgFilter = new IntentFilter();
6806 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6807 pkgFilter.addDataScheme("package");
6808 mContext.registerReceiver(new BroadcastReceiver() {
6810 public void onReceive(Context context, Intent intent) {
6811 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6813 for (String pkg : pkgs) {
6814 synchronized (ActivityManagerService.this) {
6815 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6816 0, "query restart")) {
6817 setResultCode(Activity.RESULT_OK);
6826 IntentFilter dumpheapFilter = new IntentFilter();
6827 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6828 mContext.registerReceiver(new BroadcastReceiver() {
6830 public void onReceive(Context context, Intent intent) {
6831 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6832 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6834 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6839 // Let system services know.
6840 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6842 synchronized (this) {
6843 // Ensure that any processes we had put on hold are now started
6845 final int NP = mProcessesOnHold.size();
6847 ArrayList<ProcessRecord> procs =
6848 new ArrayList<ProcessRecord>(mProcessesOnHold);
6849 for (int ip=0; ip<NP; ip++) {
6850 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6852 startProcessLocked(procs.get(ip), "on-hold", null);
6856 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6857 // Start looking for apps that are abusing wake locks.
6858 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6859 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6860 // Tell anyone interested that we are done booting!
6861 SystemProperties.set("sys.boot_completed", "1");
6863 // And trigger dev.bootcomplete if we are not showing encryption progress
6864 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6865 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6866 SystemProperties.set("dev.bootcomplete", "1");
6868 mUserController.sendBootCompletedLocked(
6869 new IIntentReceiver.Stub() {
6871 public void performReceive(Intent intent, int resultCode,
6872 String data, Bundle extras, boolean ordered,
6873 boolean sticky, int sendingUser) {
6874 synchronized (ActivityManagerService.this) {
6875 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6880 scheduleStartProfilesLocked();
6886 public void bootAnimationComplete() {
6887 final boolean callFinishBooting;
6888 synchronized (this) {
6889 callFinishBooting = mCallFinishBooting;
6890 mBootAnimationComplete = true;
6892 if (callFinishBooting) {
6893 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6895 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6899 final void ensureBootCompleted() {
6901 boolean enableScreen;
6902 synchronized (this) {
6905 enableScreen = !mBooted;
6910 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6912 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6916 enableScreenAfterBoot();
6921 public final void activityResumed(IBinder token) {
6922 final long origId = Binder.clearCallingIdentity();
6923 synchronized(this) {
6924 ActivityStack stack = ActivityRecord.getStackLocked(token);
6925 if (stack != null) {
6926 stack.activityResumedLocked(token);
6929 Binder.restoreCallingIdentity(origId);
6933 public final void activityPaused(IBinder token) {
6934 final long origId = Binder.clearCallingIdentity();
6935 synchronized(this) {
6936 ActivityStack stack = ActivityRecord.getStackLocked(token);
6937 if (stack != null) {
6938 stack.activityPausedLocked(token, false);
6941 Binder.restoreCallingIdentity(origId);
6945 public final void activityStopped(IBinder token, Bundle icicle,
6946 PersistableBundle persistentState, CharSequence description) {
6947 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6949 // Refuse possible leaked file descriptors
6950 if (icicle != null && icicle.hasFileDescriptors()) {
6951 throw new IllegalArgumentException("File descriptors passed in Bundle");
6954 final long origId = Binder.clearCallingIdentity();
6956 synchronized (this) {
6957 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6959 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6965 Binder.restoreCallingIdentity(origId);
6969 public final void activityDestroyed(IBinder token) {
6970 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6971 synchronized (this) {
6972 ActivityStack stack = ActivityRecord.getStackLocked(token);
6973 if (stack != null) {
6974 stack.activityDestroyedLocked(token, "activityDestroyed");
6980 public final void activityRelaunched(IBinder token) {
6981 final long origId = Binder.clearCallingIdentity();
6982 synchronized (this) {
6983 mStackSupervisor.activityRelaunchedLocked(token);
6985 Binder.restoreCallingIdentity(origId);
6989 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6990 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6991 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6992 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6993 synchronized (this) {
6994 ActivityRecord record = ActivityRecord.isInStackLocked(token);
6995 if (record == null) {
6996 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6997 + "found for: " + token);
6999 record.setSizeConfigurations(horizontalSizeConfiguration,
7000 verticalSizeConfigurations, smallestSizeConfigurations);
7005 public final void backgroundResourcesReleased(IBinder token) {
7006 final long origId = Binder.clearCallingIdentity();
7008 synchronized (this) {
7009 ActivityStack stack = ActivityRecord.getStackLocked(token);
7010 if (stack != null) {
7011 stack.backgroundResourcesReleased();
7015 Binder.restoreCallingIdentity(origId);
7020 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7021 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7025 public final void notifyEnterAnimationComplete(IBinder token) {
7026 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7030 public String getCallingPackage(IBinder token) {
7031 synchronized (this) {
7032 ActivityRecord r = getCallingRecordLocked(token);
7033 return r != null ? r.info.packageName : null;
7038 public ComponentName getCallingActivity(IBinder token) {
7039 synchronized (this) {
7040 ActivityRecord r = getCallingRecordLocked(token);
7041 return r != null ? r.intent.getComponent() : null;
7045 private ActivityRecord getCallingRecordLocked(IBinder token) {
7046 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7054 public ComponentName getActivityClassForToken(IBinder token) {
7055 synchronized(this) {
7056 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7060 return r.intent.getComponent();
7065 public String getPackageForToken(IBinder token) {
7066 synchronized(this) {
7067 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7071 return r.packageName;
7076 public boolean isRootVoiceInteraction(IBinder token) {
7077 synchronized(this) {
7078 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7082 return r.rootVoiceInteraction;
7087 public IIntentSender getIntentSender(int type,
7088 String packageName, IBinder token, String resultWho,
7089 int requestCode, Intent[] intents, String[] resolvedTypes,
7090 int flags, Bundle bOptions, int userId) {
7091 enforceNotIsolatedCaller("getIntentSender");
7092 // Refuse possible leaked file descriptors
7093 if (intents != null) {
7094 if (intents.length < 1) {
7095 throw new IllegalArgumentException("Intents array length must be >= 1");
7097 for (int i=0; i<intents.length; i++) {
7098 Intent intent = intents[i];
7099 if (intent != null) {
7100 if (intent.hasFileDescriptors()) {
7101 throw new IllegalArgumentException("File descriptors passed in Intent");
7103 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7104 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7105 throw new IllegalArgumentException(
7106 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7108 intents[i] = new Intent(intent);
7111 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7112 throw new IllegalArgumentException(
7113 "Intent array length does not match resolvedTypes length");
7116 if (bOptions != null) {
7117 if (bOptions.hasFileDescriptors()) {
7118 throw new IllegalArgumentException("File descriptors passed in options");
7122 synchronized(this) {
7123 int callingUid = Binder.getCallingUid();
7124 int origUserId = userId;
7125 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7126 type == ActivityManager.INTENT_SENDER_BROADCAST,
7127 ALLOW_NON_FULL, "getIntentSender", null);
7128 if (origUserId == UserHandle.USER_CURRENT) {
7129 // We don't want to evaluate this until the pending intent is
7130 // actually executed. However, we do want to always do the
7131 // security checking for it above.
7132 userId = UserHandle.USER_CURRENT;
7135 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7136 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7137 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7138 if (!UserHandle.isSameApp(callingUid, uid)) {
7139 String msg = "Permission Denial: getIntentSender() from pid="
7140 + Binder.getCallingPid()
7141 + ", uid=" + Binder.getCallingUid()
7142 + ", (need uid=" + uid + ")"
7143 + " is not allowed to send as package " + packageName;
7145 throw new SecurityException(msg);
7149 return getIntentSenderLocked(type, packageName, callingUid, userId,
7150 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7152 } catch (RemoteException e) {
7153 throw new SecurityException(e);
7158 IIntentSender getIntentSenderLocked(int type, String packageName,
7159 int callingUid, int userId, IBinder token, String resultWho,
7160 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7162 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7163 ActivityRecord activity = null;
7164 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7165 activity = ActivityRecord.isInStackLocked(token);
7166 if (activity == null) {
7167 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7170 if (activity.finishing) {
7171 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7176 // We're going to be splicing together extras before sending, so we're
7177 // okay poking into any contained extras.
7178 if (intents != null) {
7179 for (int i = 0; i < intents.length; i++) {
7180 intents[i].setDefusable(true);
7183 Bundle.setDefusable(bOptions, true);
7185 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7186 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7187 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7188 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7189 |PendingIntent.FLAG_UPDATE_CURRENT);
7191 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7192 type, packageName, activity, resultWho,
7193 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7194 WeakReference<PendingIntentRecord> ref;
7195 ref = mIntentSenderRecords.get(key);
7196 PendingIntentRecord rec = ref != null ? ref.get() : null;
7198 if (!cancelCurrent) {
7199 if (updateCurrent) {
7200 if (rec.key.requestIntent != null) {
7201 rec.key.requestIntent.replaceExtras(intents != null ?
7202 intents[intents.length - 1] : null);
7204 if (intents != null) {
7205 intents[intents.length-1] = rec.key.requestIntent;
7206 rec.key.allIntents = intents;
7207 rec.key.allResolvedTypes = resolvedTypes;
7209 rec.key.allIntents = null;
7210 rec.key.allResolvedTypes = null;
7215 rec.canceled = true;
7216 mIntentSenderRecords.remove(key);
7221 rec = new PendingIntentRecord(this, key, callingUid);
7222 mIntentSenderRecords.put(key, rec.ref);
7223 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7224 if (activity.pendingResults == null) {
7225 activity.pendingResults
7226 = new HashSet<WeakReference<PendingIntentRecord>>();
7228 activity.pendingResults.add(rec.ref);
7234 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7235 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7236 if (target instanceof PendingIntentRecord) {
7237 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7238 finishedReceiver, requiredPermission, options);
7240 if (intent == null) {
7241 // Weird case: someone has given us their own custom IIntentSender, and now
7242 // they have someone else trying to send to it but of course this isn't
7243 // really a PendingIntent, so there is no base Intent, and the caller isn't
7244 // supplying an Intent... but we never want to dispatch a null Intent to
7245 // a receiver, so um... let's make something up.
7246 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7247 intent = new Intent(Intent.ACTION_MAIN);
7250 target.send(code, intent, resolvedType, null, requiredPermission, options);
7251 } catch (RemoteException e) {
7253 // Platform code can rely on getting a result back when the send is done, but if
7254 // this intent sender is from outside of the system we can't rely on it doing that.
7255 // So instead we don't give it the result receiver, and instead just directly
7256 // report the finish immediately.
7257 if (finishedReceiver != null) {
7259 finishedReceiver.performReceive(intent, 0,
7260 null, null, false, false, UserHandle.getCallingUserId());
7261 } catch (RemoteException e) {
7269 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7271 * <p>{@code callerUid} must be allowed to request such whitelist by calling
7272 * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7274 void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7275 if (DEBUG_WHITELISTS) {
7276 Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7277 + targetUid + ", " + duration + ")");
7279 synchronized (mPidsSelfLocked) {
7280 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7282 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7285 if (!pr.whitelistManager) {
7286 if (DEBUG_WHITELISTS) {
7287 Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7288 + callerPid + " is not allowed");
7294 final long token = Binder.clearCallingIdentity();
7296 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7297 true, "pe from uid:" + callerUid);
7299 Binder.restoreCallingIdentity(token);
7304 public void cancelIntentSender(IIntentSender sender) {
7305 if (!(sender instanceof PendingIntentRecord)) {
7308 synchronized(this) {
7309 PendingIntentRecord rec = (PendingIntentRecord)sender;
7311 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7312 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7313 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7314 String msg = "Permission Denial: cancelIntentSender() from pid="
7315 + Binder.getCallingPid()
7316 + ", uid=" + Binder.getCallingUid()
7317 + " is not allowed to cancel packges "
7318 + rec.key.packageName;
7320 throw new SecurityException(msg);
7322 } catch (RemoteException e) {
7323 throw new SecurityException(e);
7325 cancelIntentSenderLocked(rec, true);
7329 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7330 rec.canceled = true;
7331 mIntentSenderRecords.remove(rec.key);
7332 if (cleanActivity && rec.key.activity != null) {
7333 rec.key.activity.pendingResults.remove(rec.ref);
7338 public String getPackageForIntentSender(IIntentSender pendingResult) {
7339 if (!(pendingResult instanceof PendingIntentRecord)) {
7343 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7344 return res.key.packageName;
7345 } catch (ClassCastException e) {
7351 public int getUidForIntentSender(IIntentSender sender) {
7352 if (sender instanceof PendingIntentRecord) {
7354 PendingIntentRecord res = (PendingIntentRecord)sender;
7356 } catch (ClassCastException e) {
7363 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7364 if (!(pendingResult instanceof PendingIntentRecord)) {
7368 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7369 if (res.key.allIntents == null) {
7372 for (int i=0; i<res.key.allIntents.length; i++) {
7373 Intent intent = res.key.allIntents[i];
7374 if (intent.getPackage() != null && intent.getComponent() != null) {
7379 } catch (ClassCastException e) {
7385 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7386 if (!(pendingResult instanceof PendingIntentRecord)) {
7390 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7391 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7395 } catch (ClassCastException e) {
7401 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7402 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7403 "getIntentForIntentSender()");
7404 if (!(pendingResult instanceof PendingIntentRecord)) {
7408 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7409 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7410 } catch (ClassCastException e) {
7416 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7417 if (!(pendingResult instanceof PendingIntentRecord)) {
7421 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7422 synchronized (this) {
7423 return getTagForIntentSenderLocked(res, prefix);
7425 } catch (ClassCastException e) {
7430 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7431 final Intent intent = res.key.requestIntent;
7432 if (intent != null) {
7433 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7434 || res.lastTagPrefix.equals(prefix))) {
7437 res.lastTagPrefix = prefix;
7438 final StringBuilder sb = new StringBuilder(128);
7439 if (prefix != null) {
7442 if (intent.getAction() != null) {
7443 sb.append(intent.getAction());
7444 } else if (intent.getComponent() != null) {
7445 intent.getComponent().appendShortString(sb);
7449 return res.lastTag = sb.toString();
7455 public void setProcessLimit(int max) {
7456 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7457 "setProcessLimit()");
7458 synchronized (this) {
7459 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7460 mProcessLimitOverride = max;
7466 public int getProcessLimit() {
7467 synchronized (this) {
7468 return mProcessLimitOverride;
7472 void foregroundTokenDied(ForegroundToken token) {
7473 synchronized (ActivityManagerService.this) {
7474 synchronized (mPidsSelfLocked) {
7476 = mForegroundProcesses.get(token.pid);
7480 mForegroundProcesses.remove(token.pid);
7481 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7485 pr.forcingToForeground = null;
7486 updateProcessForegroundLocked(pr, false, false);
7488 updateOomAdjLocked();
7493 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7494 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7495 "setProcessForeground()");
7496 synchronized(this) {
7497 boolean changed = false;
7499 synchronized (mPidsSelfLocked) {
7500 ProcessRecord pr = mPidsSelfLocked.get(pid);
7501 if (pr == null && isForeground) {
7502 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7505 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7506 if (oldToken != null) {
7507 oldToken.token.unlinkToDeath(oldToken, 0);
7508 mForegroundProcesses.remove(pid);
7510 pr.forcingToForeground = null;
7514 if (isForeground && token != null) {
7515 ForegroundToken newToken = new ForegroundToken() {
7517 public void binderDied() {
7518 foregroundTokenDied(this);
7522 newToken.token = token;
7524 token.linkToDeath(newToken, 0);
7525 mForegroundProcesses.put(pid, newToken);
7526 pr.forcingToForeground = token;
7528 } catch (RemoteException e) {
7529 // If the process died while doing this, we will later
7530 // do the cleanup with the process death link.
7536 updateOomAdjLocked();
7542 public boolean isAppForeground(int uid) throws RemoteException {
7543 synchronized (this) {
7544 UidRecord uidRec = mActiveUids.get(uid);
7545 if (uidRec == null || uidRec.idle) {
7548 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7552 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7553 // be guarded by permission checking.
7554 int getUidState(int uid) {
7555 synchronized (this) {
7556 UidRecord uidRec = mActiveUids.get(uid);
7557 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7562 public boolean isInMultiWindowMode(IBinder token) {
7563 final long origId = Binder.clearCallingIdentity();
7565 synchronized(this) {
7566 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7570 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7571 return !r.task.mFullscreen;
7574 Binder.restoreCallingIdentity(origId);
7579 public boolean isInPictureInPictureMode(IBinder token) {
7580 final long origId = Binder.clearCallingIdentity();
7582 synchronized(this) {
7583 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7584 if (stack == null) {
7587 return stack.mStackId == PINNED_STACK_ID;
7590 Binder.restoreCallingIdentity(origId);
7595 public void enterPictureInPictureMode(IBinder token) {
7596 final long origId = Binder.clearCallingIdentity();
7598 synchronized(this) {
7599 if (!mSupportsPictureInPicture) {
7600 throw new IllegalStateException("enterPictureInPictureMode: "
7601 + "Device doesn't support picture-in-picture mode.");
7604 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7607 throw new IllegalStateException("enterPictureInPictureMode: "
7608 + "Can't find activity for token=" + token);
7611 if (!r.supportsPictureInPicture()) {
7612 throw new IllegalArgumentException("enterPictureInPictureMode: "
7613 + "Picture-In-Picture not supported for r=" + r);
7616 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7618 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7619 final Rect bounds = (pinnedStack != null)
7620 ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7622 mStackSupervisor.moveActivityToPinnedStackLocked(
7623 r, "enterPictureInPictureMode", bounds);
7626 Binder.restoreCallingIdentity(origId);
7630 // =========================================================
7632 // =========================================================
7634 static class ProcessInfoService extends IProcessInfoService.Stub {
7635 final ActivityManagerService mActivityManagerService;
7636 ProcessInfoService(ActivityManagerService activityManagerService) {
7637 mActivityManagerService = activityManagerService;
7641 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7642 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7643 /*in*/ pids, /*out*/ states, null);
7647 public void getProcessStatesAndOomScoresFromPids(
7648 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7649 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7650 /*in*/ pids, /*out*/ states, /*out*/ scores);
7655 * For each PID in the given input array, write the current process state
7656 * for that process into the states array, or -1 to indicate that no
7657 * process with the given PID exists. If scores array is provided, write
7658 * the oom score for the process into the scores array, with INVALID_ADJ
7659 * indicating the PID doesn't exist.
7661 public void getProcessStatesAndOomScoresForPIDs(
7662 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7663 if (scores != null) {
7664 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7665 "getProcessStatesAndOomScoresForPIDs()");
7669 throw new NullPointerException("pids");
7670 } else if (states == null) {
7671 throw new NullPointerException("states");
7672 } else if (pids.length != states.length) {
7673 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7674 } else if (scores != null && pids.length != scores.length) {
7675 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7678 synchronized (mPidsSelfLocked) {
7679 for (int i = 0; i < pids.length; i++) {
7680 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7681 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7683 if (scores != null) {
7684 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7690 // =========================================================
7692 // =========================================================
7694 static class PermissionController extends IPermissionController.Stub {
7695 ActivityManagerService mActivityManagerService;
7696 PermissionController(ActivityManagerService activityManagerService) {
7697 mActivityManagerService = activityManagerService;
7701 public boolean checkPermission(String permission, int pid, int uid) {
7702 return mActivityManagerService.checkPermission(permission, pid,
7703 uid) == PackageManager.PERMISSION_GRANTED;
7707 public String[] getPackagesForUid(int uid) {
7708 return mActivityManagerService.mContext.getPackageManager()
7709 .getPackagesForUid(uid);
7713 public boolean isRuntimePermission(String permission) {
7715 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7716 .getPermissionInfo(permission, 0);
7717 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7718 } catch (NameNotFoundException nnfe) {
7719 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7725 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7727 public int checkComponentPermission(String permission, int pid, int uid,
7728 int owningUid, boolean exported) {
7729 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7730 owningUid, exported);
7734 public Object getAMSLock() {
7735 return ActivityManagerService.this;
7740 * This can be called with or without the global lock held.
7742 int checkComponentPermission(String permission, int pid, int uid,
7743 int owningUid, boolean exported) {
7744 if (pid == MY_PID) {
7745 return PackageManager.PERMISSION_GRANTED;
7747 return ActivityManager.checkComponentPermission(permission, uid,
7748 owningUid, exported);
7752 * As the only public entry point for permissions checking, this method
7753 * can enforce the semantic that requesting a check on a null global
7754 * permission is automatically denied. (Internally a null permission
7755 * string is used when calling {@link #checkComponentPermission} in cases
7756 * when only uid-based security is needed.)
7758 * This can be called with or without the global lock held.
7761 public int checkPermission(String permission, int pid, int uid) {
7762 if (permission == null) {
7763 return PackageManager.PERMISSION_DENIED;
7765 return checkComponentPermission(permission, pid, uid, -1, true);
7769 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7770 if (permission == null) {
7771 return PackageManager.PERMISSION_DENIED;
7774 // We might be performing an operation on behalf of an indirect binder
7775 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7776 // client identity accordingly before proceeding.
7777 Identity tlsIdentity = sCallerIdentity.get();
7778 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7779 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7780 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7781 uid = tlsIdentity.uid;
7782 pid = tlsIdentity.pid;
7785 return checkComponentPermission(permission, pid, uid, -1, true);
7789 * Binder IPC calls go through the public entry point.
7790 * This can be called with or without the global lock held.
7792 int checkCallingPermission(String permission) {
7793 return checkPermission(permission,
7794 Binder.getCallingPid(),
7795 UserHandle.getAppId(Binder.getCallingUid()));
7799 * This can be called with or without the global lock held.
7801 void enforceCallingPermission(String permission, String func) {
7802 if (checkCallingPermission(permission)
7803 == PackageManager.PERMISSION_GRANTED) {
7807 String msg = "Permission Denial: " + func + " from pid="
7808 + Binder.getCallingPid()
7809 + ", uid=" + Binder.getCallingUid()
7810 + " requires " + permission;
7812 throw new SecurityException(msg);
7816 * Determine if UID is holding permissions required to access {@link Uri} in
7817 * the given {@link ProviderInfo}. Final permission checking is always done
7818 * in {@link ContentProvider}.
7820 private final boolean checkHoldingPermissionsLocked(
7821 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7822 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7823 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7824 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7825 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7826 != PERMISSION_GRANTED) {
7830 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7833 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7834 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7835 if (pi.applicationInfo.uid == uid) {
7837 } else if (!pi.exported) {
7841 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7842 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7844 // check if target holds top-level <provider> permissions
7845 if (!readMet && pi.readPermission != null && considerUidPermissions
7846 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7849 if (!writeMet && pi.writePermission != null && considerUidPermissions
7850 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7854 // track if unprotected read/write is allowed; any denied
7855 // <path-permission> below removes this ability
7856 boolean allowDefaultRead = pi.readPermission == null;
7857 boolean allowDefaultWrite = pi.writePermission == null;
7859 // check if target holds any <path-permission> that match uri
7860 final PathPermission[] pps = pi.pathPermissions;
7862 final String path = grantUri.uri.getPath();
7864 while (i > 0 && (!readMet || !writeMet)) {
7866 PathPermission pp = pps[i];
7867 if (pp.match(path)) {
7869 final String pprperm = pp.getReadPermission();
7870 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7871 "Checking read perm for " + pprperm + " for " + pp.getPath()
7872 + ": match=" + pp.match(path)
7873 + " check=" + pm.checkUidPermission(pprperm, uid));
7874 if (pprperm != null) {
7875 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7876 == PERMISSION_GRANTED) {
7879 allowDefaultRead = false;
7884 final String ppwperm = pp.getWritePermission();
7885 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7886 "Checking write perm " + ppwperm + " for " + pp.getPath()
7887 + ": match=" + pp.match(path)
7888 + " check=" + pm.checkUidPermission(ppwperm, uid));
7889 if (ppwperm != null) {
7890 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7891 == PERMISSION_GRANTED) {
7894 allowDefaultWrite = false;
7902 // grant unprotected <provider> read/write, if not blocked by
7903 // <path-permission> above
7904 if (allowDefaultRead) readMet = true;
7905 if (allowDefaultWrite) writeMet = true;
7907 } catch (RemoteException e) {
7911 return readMet && writeMet;
7914 public int getAppStartMode(int uid, String packageName) {
7915 synchronized (this) {
7916 return checkAllowBackgroundLocked(uid, packageName, -1, true);
7920 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7921 boolean allowWhenForeground) {
7922 UidRecord uidRec = mActiveUids.get(uid);
7923 if (!mLenientBackgroundCheck) {
7924 if (!allowWhenForeground || uidRec == null
7925 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7926 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7927 packageName) != AppOpsManager.MODE_ALLOWED) {
7928 return ActivityManager.APP_START_MODE_DELAYED;
7932 } else if (uidRec == null || uidRec.idle) {
7933 if (callingPid >= 0) {
7935 synchronized (mPidsSelfLocked) {
7936 proc = mPidsSelfLocked.get(callingPid);
7938 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7939 // Whoever is instigating this is in the foreground, so we will allow it
7941 return ActivityManager.APP_START_MODE_NORMAL;
7944 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7945 != AppOpsManager.MODE_ALLOWED) {
7946 return ActivityManager.APP_START_MODE_DELAYED;
7949 return ActivityManager.APP_START_MODE_NORMAL;
7952 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7953 ProviderInfo pi = null;
7954 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7959 pi = AppGlobals.getPackageManager().resolveContentProvider(
7960 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7962 } catch (RemoteException ex) {
7968 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7969 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7970 if (targetUris != null) {
7971 return targetUris.get(grantUri);
7976 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7977 String targetPkg, int targetUid, GrantUri grantUri) {
7978 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7979 if (targetUris == null) {
7980 targetUris = Maps.newArrayMap();
7981 mGrantedUriPermissions.put(targetUid, targetUris);
7984 UriPermission perm = targetUris.get(grantUri);
7986 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7987 targetUris.put(grantUri, perm);
7993 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7994 final int modeFlags) {
7995 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7996 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7997 : UriPermission.STRENGTH_OWNED;
7999 // Root gets to do everything.
8004 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8005 if (perms == null) return false;
8007 // First look for exact match
8008 final UriPermission exactPerm = perms.get(grantUri);
8009 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8013 // No exact match, look for prefixes
8014 final int N = perms.size();
8015 for (int i = 0; i < N; i++) {
8016 final UriPermission perm = perms.valueAt(i);
8017 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8018 && perm.getStrength(modeFlags) >= minStrength) {
8027 * @param uri This uri must NOT contain an embedded userId.
8028 * @param userId The userId in which the uri is to be resolved.
8031 public int checkUriPermission(Uri uri, int pid, int uid,
8032 final int modeFlags, int userId, IBinder callerToken) {
8033 enforceNotIsolatedCaller("checkUriPermission");
8035 // Another redirected-binder-call permissions check as in
8036 // {@link checkPermissionWithToken}.
8037 Identity tlsIdentity = sCallerIdentity.get();
8038 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8039 uid = tlsIdentity.uid;
8040 pid = tlsIdentity.pid;
8043 // Our own process gets to do everything.
8044 if (pid == MY_PID) {
8045 return PackageManager.PERMISSION_GRANTED;
8047 synchronized (this) {
8048 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8049 ? PackageManager.PERMISSION_GRANTED
8050 : PackageManager.PERMISSION_DENIED;
8055 * Check if the targetPkg can be granted permission to access uri by
8056 * the callingUid using the given modeFlags. Throws a security exception
8057 * if callingUid is not allowed to do this. Returns the uid of the target
8058 * if the URI permission grant should be performed; returns -1 if it is not
8059 * needed (for example targetPkg already has permission to access the URI).
8060 * If you already know the uid of the target, you can supply it in
8061 * lastTargetUid else set that to -1.
8063 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8064 final int modeFlags, int lastTargetUid) {
8065 if (!Intent.isAccessUriMode(modeFlags)) {
8069 if (targetPkg != null) {
8070 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8071 "Checking grant " + targetPkg + " permission to " + grantUri);
8074 final IPackageManager pm = AppGlobals.getPackageManager();
8076 // If this is not a content: uri, we can't do anything with it.
8077 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8078 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079 "Can't grant URI permission for non-content URI: " + grantUri);
8083 final String authority = grantUri.uri.getAuthority();
8084 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8085 MATCH_DEBUG_TRIAGED_MISSING);
8087 Slog.w(TAG, "No content provider found for permission check: " +
8088 grantUri.uri.toSafeString());
8092 int targetUid = lastTargetUid;
8093 if (targetUid < 0 && targetPkg != null) {
8095 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8096 UserHandle.getUserId(callingUid));
8097 if (targetUid < 0) {
8098 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099 "Can't grant URI permission no uid for: " + targetPkg);
8102 } catch (RemoteException ex) {
8107 if (targetUid >= 0) {
8108 // First... does the target actually need this permission?
8109 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8110 // No need to grant the target this permission.
8111 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8112 "Target " + targetPkg + " already has full permission to " + grantUri);
8116 // First... there is no target package, so can anyone access it?
8117 boolean allowed = pi.exported;
8118 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8119 if (pi.readPermission != null) {
8123 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8124 if (pi.writePermission != null) {
8133 /* There is a special cross user grant if:
8134 * - The target is on another user.
8135 * - Apps on the current user can access the uri without any uid permissions.
8136 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8137 * grant uri permissions.
8139 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8140 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8141 modeFlags, false /*without considering the uid permissions*/);
8143 // Second... is the provider allowing granting of URI permissions?
8144 if (!specialCrossUserGrant) {
8145 if (!pi.grantUriPermissions) {
8146 throw new SecurityException("Provider " + pi.packageName
8148 + " does not allow granting of Uri permissions (uri "
8151 if (pi.uriPermissionPatterns != null) {
8152 final int N = pi.uriPermissionPatterns.length;
8153 boolean allowed = false;
8154 for (int i=0; i<N; i++) {
8155 if (pi.uriPermissionPatterns[i] != null
8156 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8162 throw new SecurityException("Provider " + pi.packageName
8164 + " does not allow granting of permission to path of Uri "
8170 // Third... does the caller itself have permission to access
8172 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8173 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8174 // Require they hold a strong enough Uri permission
8175 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8176 throw new SecurityException("Uid " + callingUid
8177 + " does not have permission to uri " + grantUri);
8185 * @param uri This uri must NOT contain an embedded userId.
8186 * @param userId The userId in which the uri is to be resolved.
8189 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8190 final int modeFlags, int userId) {
8191 enforceNotIsolatedCaller("checkGrantUriPermission");
8192 synchronized(this) {
8193 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8194 new GrantUri(userId, uri, false), modeFlags, -1);
8198 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8199 final int modeFlags, UriPermissionOwner owner) {
8200 if (!Intent.isAccessUriMode(modeFlags)) {
8204 // So here we are: the caller has the assumed permission
8205 // to the uri, and the target doesn't. Let's now give this to
8208 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8209 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8211 final String authority = grantUri.uri.getAuthority();
8212 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8213 MATCH_DEBUG_TRIAGED_MISSING);
8215 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8219 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8220 grantUri.prefix = true;
8222 final UriPermission perm = findOrCreateUriPermissionLocked(
8223 pi.packageName, targetPkg, targetUid, grantUri);
8224 perm.grantModes(modeFlags, owner);
8227 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8228 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8229 if (targetPkg == null) {
8230 throw new NullPointerException("targetPkg");
8233 final IPackageManager pm = AppGlobals.getPackageManager();
8235 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8236 } catch (RemoteException ex) {
8240 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8242 if (targetUid < 0) {
8246 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8250 static class NeededUriGrants extends ArrayList<GrantUri> {
8251 final String targetPkg;
8252 final int targetUid;
8255 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8256 this.targetPkg = targetPkg;
8257 this.targetUid = targetUid;
8263 * Like checkGrantUriPermissionLocked, but takes an Intent.
8265 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8266 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8267 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8268 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8269 + " clip=" + (intent != null ? intent.getClipData() : null)
8270 + " from " + intent + "; flags=0x"
8271 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8273 if (targetPkg == null) {
8274 throw new NullPointerException("targetPkg");
8277 if (intent == null) {
8280 Uri data = intent.getData();
8281 ClipData clip = intent.getClipData();
8282 if (data == null && clip == null) {
8285 // Default userId for uris in the intent (if they don't specify it themselves)
8286 int contentUserHint = intent.getContentUserHint();
8287 if (contentUserHint == UserHandle.USER_CURRENT) {
8288 contentUserHint = UserHandle.getUserId(callingUid);
8290 final IPackageManager pm = AppGlobals.getPackageManager();
8292 if (needed != null) {
8293 targetUid = needed.targetUid;
8296 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8298 } catch (RemoteException ex) {
8301 if (targetUid < 0) {
8302 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8303 "Can't grant URI permission no uid for: " + targetPkg
8304 + " on user " + targetUserId);
8309 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8310 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8312 if (targetUid > 0) {
8313 if (needed == null) {
8314 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8316 needed.add(grantUri);
8320 for (int i=0; i<clip.getItemCount(); i++) {
8321 Uri uri = clip.getItemAt(i).getUri();
8323 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8324 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8326 if (targetUid > 0) {
8327 if (needed == null) {
8328 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8330 needed.add(grantUri);
8333 Intent clipIntent = clip.getItemAt(i).getIntent();
8334 if (clipIntent != null) {
8335 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8336 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8337 if (newNeeded != null) {
8349 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8351 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8352 UriPermissionOwner owner) {
8353 if (needed != null) {
8354 for (int i=0; i<needed.size(); i++) {
8355 GrantUri grantUri = needed.get(i);
8356 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8357 grantUri, needed.flags, owner);
8362 void grantUriPermissionFromIntentLocked(int callingUid,
8363 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8364 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8365 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8366 if (needed == null) {
8370 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8374 * @param uri This uri must NOT contain an embedded userId.
8375 * @param userId The userId in which the uri is to be resolved.
8378 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8379 final int modeFlags, int userId) {
8380 enforceNotIsolatedCaller("grantUriPermission");
8381 GrantUri grantUri = new GrantUri(userId, uri, false);
8382 synchronized(this) {
8383 final ProcessRecord r = getRecordForAppLocked(caller);
8385 throw new SecurityException("Unable to find app for caller "
8387 + " when granting permission to uri " + grantUri);
8389 if (targetPkg == null) {
8390 throw new IllegalArgumentException("null target");
8392 if (grantUri == null) {
8393 throw new IllegalArgumentException("null uri");
8396 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8397 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8398 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8399 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8401 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8402 UserHandle.getUserId(r.uid));
8406 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8407 if (perm.modeFlags == 0) {
8408 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8410 if (perms != null) {
8411 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8412 "Removing " + perm.targetUid + " permission to " + perm.uri);
8414 perms.remove(perm.uri);
8415 if (perms.isEmpty()) {
8416 mGrantedUriPermissions.remove(perm.targetUid);
8422 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8423 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8424 "Revoking all granted permissions to " + grantUri);
8426 final IPackageManager pm = AppGlobals.getPackageManager();
8427 final String authority = grantUri.uri.getAuthority();
8428 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8429 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8431 Slog.w(TAG, "No content provider found for permission revoke: "
8432 + grantUri.toSafeString());
8436 // Does the caller have this permission on the URI?
8437 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8438 // If they don't have direct access to the URI, then revoke any
8439 // ownerless URI permissions that have been granted to them.
8440 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8441 if (perms != null) {
8442 boolean persistChanged = false;
8443 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8444 final UriPermission perm = it.next();
8445 if (perm.uri.sourceUserId == grantUri.sourceUserId
8446 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8447 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8448 "Revoking non-owned " + perm.targetUid
8449 + " permission to " + perm.uri);
8450 persistChanged |= perm.revokeModes(
8451 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8452 if (perm.modeFlags == 0) {
8457 if (perms.isEmpty()) {
8458 mGrantedUriPermissions.remove(callingUid);
8460 if (persistChanged) {
8461 schedulePersistUriGrants();
8467 boolean persistChanged = false;
8469 // Go through all of the permissions and remove any that match.
8470 int N = mGrantedUriPermissions.size();
8471 for (int i = 0; i < N; i++) {
8472 final int targetUid = mGrantedUriPermissions.keyAt(i);
8473 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8475 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8476 final UriPermission perm = it.next();
8477 if (perm.uri.sourceUserId == grantUri.sourceUserId
8478 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8479 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8480 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8481 persistChanged |= perm.revokeModes(
8482 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8483 if (perm.modeFlags == 0) {
8489 if (perms.isEmpty()) {
8490 mGrantedUriPermissions.remove(targetUid);
8496 if (persistChanged) {
8497 schedulePersistUriGrants();
8502 * @param uri This uri must NOT contain an embedded userId.
8503 * @param userId The userId in which the uri is to be resolved.
8506 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8508 enforceNotIsolatedCaller("revokeUriPermission");
8509 synchronized(this) {
8510 final ProcessRecord r = getRecordForAppLocked(caller);
8512 throw new SecurityException("Unable to find app for caller "
8514 + " when revoking permission to uri " + uri);
8517 Slog.w(TAG, "revokeUriPermission: null uri");
8521 if (!Intent.isAccessUriMode(modeFlags)) {
8525 final String authority = uri.getAuthority();
8526 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8527 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8529 Slog.w(TAG, "No content provider found for permission revoke: "
8530 + uri.toSafeString());
8534 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8539 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8542 * @param packageName Package name to match, or {@code null} to apply to all
8544 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8546 * @param persistable If persistable grants should be removed.
8548 private void removeUriPermissionsForPackageLocked(
8549 String packageName, int userHandle, boolean persistable) {
8550 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8551 throw new IllegalArgumentException("Must narrow by either package or user");
8554 boolean persistChanged = false;
8556 int N = mGrantedUriPermissions.size();
8557 for (int i = 0; i < N; i++) {
8558 final int targetUid = mGrantedUriPermissions.keyAt(i);
8559 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8561 // Only inspect grants matching user
8562 if (userHandle == UserHandle.USER_ALL
8563 || userHandle == UserHandle.getUserId(targetUid)) {
8564 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8565 final UriPermission perm = it.next();
8567 // Only inspect grants matching package
8568 if (packageName == null || perm.sourcePkg.equals(packageName)
8569 || perm.targetPkg.equals(packageName)) {
8570 // Hacky solution as part of fixing a security bug; ignore
8571 // grants associated with DownloadManager so we don't have
8572 // to immediately launch it to regrant the permissions
8573 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8574 && !persistable) continue;
8576 persistChanged |= perm.revokeModes(persistable
8577 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8579 // Only remove when no modes remain; any persisted grants
8580 // will keep this alive.
8581 if (perm.modeFlags == 0) {
8587 if (perms.isEmpty()) {
8588 mGrantedUriPermissions.remove(targetUid);
8595 if (persistChanged) {
8596 schedulePersistUriGrants();
8601 public IBinder newUriPermissionOwner(String name) {
8602 enforceNotIsolatedCaller("newUriPermissionOwner");
8603 synchronized(this) {
8604 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8605 return owner.getExternalTokenLocked();
8610 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8611 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8612 synchronized(this) {
8613 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8615 throw new IllegalArgumentException("Activity does not exist; token="
8618 return r.getUriPermissionsLocked().getExternalTokenLocked();
8622 * @param uri This uri must NOT contain an embedded userId.
8623 * @param sourceUserId The userId in which the uri is to be resolved.
8624 * @param targetUserId The userId of the app that receives the grant.
8627 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8628 final int modeFlags, int sourceUserId, int targetUserId) {
8629 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8630 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8631 "grantUriPermissionFromOwner", null);
8632 synchronized(this) {
8633 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8634 if (owner == null) {
8635 throw new IllegalArgumentException("Unknown owner: " + token);
8637 if (fromUid != Binder.getCallingUid()) {
8638 if (Binder.getCallingUid() != Process.myUid()) {
8639 // Only system code can grant URI permissions on behalf
8641 throw new SecurityException("nice try");
8644 if (targetPkg == null) {
8645 throw new IllegalArgumentException("null target");
8648 throw new IllegalArgumentException("null uri");
8651 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8652 modeFlags, owner, targetUserId);
8657 * @param uri This uri must NOT contain an embedded userId.
8658 * @param userId The userId in which the uri is to be resolved.
8661 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8662 synchronized(this) {
8663 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8664 if (owner == null) {
8665 throw new IllegalArgumentException("Unknown owner: " + token);
8669 owner.removeUriPermissionsLocked(mode);
8671 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8672 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8677 private void schedulePersistUriGrants() {
8678 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8679 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8680 10 * DateUtils.SECOND_IN_MILLIS);
8684 private void writeGrantedUriPermissions() {
8685 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8687 // Snapshot permissions so we can persist without lock
8688 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8689 synchronized (this) {
8690 final int size = mGrantedUriPermissions.size();
8691 for (int i = 0; i < size; i++) {
8692 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8693 for (UriPermission perm : perms.values()) {
8694 if (perm.persistedModeFlags != 0) {
8695 persist.add(perm.snapshot());
8701 FileOutputStream fos = null;
8703 fos = mGrantFile.startWrite();
8705 XmlSerializer out = new FastXmlSerializer();
8706 out.setOutput(fos, StandardCharsets.UTF_8.name());
8707 out.startDocument(null, true);
8708 out.startTag(null, TAG_URI_GRANTS);
8709 for (UriPermission.Snapshot perm : persist) {
8710 out.startTag(null, TAG_URI_GRANT);
8711 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8712 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8713 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8714 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8715 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8716 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8717 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8718 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8719 out.endTag(null, TAG_URI_GRANT);
8721 out.endTag(null, TAG_URI_GRANTS);
8724 mGrantFile.finishWrite(fos);
8725 } catch (IOException e) {
8727 mGrantFile.failWrite(fos);
8732 private void readGrantedUriPermissionsLocked() {
8733 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8735 final long now = System.currentTimeMillis();
8737 FileInputStream fis = null;
8739 fis = mGrantFile.openRead();
8740 final XmlPullParser in = Xml.newPullParser();
8741 in.setInput(fis, StandardCharsets.UTF_8.name());
8744 while ((type = in.next()) != END_DOCUMENT) {
8745 final String tag = in.getName();
8746 if (type == START_TAG) {
8747 if (TAG_URI_GRANT.equals(tag)) {
8748 final int sourceUserId;
8749 final int targetUserId;
8750 final int userHandle = readIntAttribute(in,
8751 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8752 if (userHandle != UserHandle.USER_NULL) {
8753 // For backwards compatibility.
8754 sourceUserId = userHandle;
8755 targetUserId = userHandle;
8757 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8758 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8760 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8761 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8762 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8763 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8764 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8765 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8767 // Sanity check that provider still belongs to source package
8768 // Both direct boot aware and unaware packages are fine as we
8769 // will do filtering at query time to avoid multiple parsing.
8770 final ProviderInfo pi = getProviderInfoLocked(
8771 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8772 | MATCH_DIRECT_BOOT_UNAWARE);
8773 if (pi != null && sourcePkg.equals(pi.packageName)) {
8776 targetUid = AppGlobals.getPackageManager().getPackageUid(
8777 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8778 } catch (RemoteException e) {
8780 if (targetUid != -1) {
8781 final UriPermission perm = findOrCreateUriPermissionLocked(
8782 sourcePkg, targetPkg, targetUid,
8783 new GrantUri(sourceUserId, uri, prefix));
8784 perm.initPersistedModes(modeFlags, createdTime);
8787 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8788 + " but instead found " + pi);
8793 } catch (FileNotFoundException e) {
8794 // Missing grants is okay
8795 } catch (IOException e) {
8796 Slog.wtf(TAG, "Failed reading Uri grants", e);
8797 } catch (XmlPullParserException e) {
8798 Slog.wtf(TAG, "Failed reading Uri grants", e);
8800 IoUtils.closeQuietly(fis);
8805 * @param uri This uri must NOT contain an embedded userId.
8806 * @param userId The userId in which the uri is to be resolved.
8809 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8810 enforceNotIsolatedCaller("takePersistableUriPermission");
8812 Preconditions.checkFlagsArgument(modeFlags,
8813 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8815 synchronized (this) {
8816 final int callingUid = Binder.getCallingUid();
8817 boolean persistChanged = false;
8818 GrantUri grantUri = new GrantUri(userId, uri, false);
8820 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8821 new GrantUri(userId, uri, false));
8822 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8823 new GrantUri(userId, uri, true));
8825 final boolean exactValid = (exactPerm != null)
8826 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8827 final boolean prefixValid = (prefixPerm != null)
8828 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8830 if (!(exactValid || prefixValid)) {
8831 throw new SecurityException("No persistable permission grants found for UID "
8832 + callingUid + " and Uri " + grantUri.toSafeString());
8836 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8839 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8842 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8844 if (persistChanged) {
8845 schedulePersistUriGrants();
8851 * @param uri This uri must NOT contain an embedded userId.
8852 * @param userId The userId in which the uri is to be resolved.
8855 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8856 enforceNotIsolatedCaller("releasePersistableUriPermission");
8858 Preconditions.checkFlagsArgument(modeFlags,
8859 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8861 synchronized (this) {
8862 final int callingUid = Binder.getCallingUid();
8863 boolean persistChanged = false;
8865 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8866 new GrantUri(userId, uri, false));
8867 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8868 new GrantUri(userId, uri, true));
8869 if (exactPerm == null && prefixPerm == null) {
8870 throw new SecurityException("No permission grants found for UID " + callingUid
8871 + " and Uri " + uri.toSafeString());
8874 if (exactPerm != null) {
8875 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8876 removeUriPermissionIfNeededLocked(exactPerm);
8878 if (prefixPerm != null) {
8879 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8880 removeUriPermissionIfNeededLocked(prefixPerm);
8883 if (persistChanged) {
8884 schedulePersistUriGrants();
8890 * Prune any older {@link UriPermission} for the given UID until outstanding
8891 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8893 * @return if any mutations occured that require persisting.
8895 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8896 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8897 if (perms == null) return false;
8898 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8900 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8901 for (UriPermission perm : perms.values()) {
8902 if (perm.persistedModeFlags != 0) {
8903 persisted.add(perm);
8907 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8908 if (trimCount <= 0) return false;
8910 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8911 for (int i = 0; i < trimCount; i++) {
8912 final UriPermission perm = persisted.get(i);
8914 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8915 "Trimming grant created at " + perm.persistedCreateTime);
8917 perm.releasePersistableModes(~0);
8918 removeUriPermissionIfNeededLocked(perm);
8925 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8926 String packageName, boolean incoming) {
8927 enforceNotIsolatedCaller("getPersistedUriPermissions");
8928 Preconditions.checkNotNull(packageName, "packageName");
8930 final int callingUid = Binder.getCallingUid();
8931 final int callingUserId = UserHandle.getUserId(callingUid);
8932 final IPackageManager pm = AppGlobals.getPackageManager();
8934 final int packageUid = pm.getPackageUid(packageName,
8935 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8936 if (packageUid != callingUid) {
8937 throw new SecurityException(
8938 "Package " + packageName + " does not belong to calling UID " + callingUid);
8940 } catch (RemoteException e) {
8941 throw new SecurityException("Failed to verify package name ownership");
8944 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8945 synchronized (this) {
8947 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8949 if (perms == null) {
8950 Slog.w(TAG, "No permission grants found for " + packageName);
8952 for (UriPermission perm : perms.values()) {
8953 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8954 result.add(perm.buildPersistedPublicApiObject());
8959 final int size = mGrantedUriPermissions.size();
8960 for (int i = 0; i < size; i++) {
8961 final ArrayMap<GrantUri, UriPermission> perms =
8962 mGrantedUriPermissions.valueAt(i);
8963 for (UriPermission perm : perms.values()) {
8964 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8965 result.add(perm.buildPersistedPublicApiObject());
8971 return new ParceledListSlice<android.content.UriPermission>(result);
8975 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8976 String packageName, int userId) {
8977 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8978 "getGrantedUriPermissions");
8980 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8981 synchronized (this) {
8982 final int size = mGrantedUriPermissions.size();
8983 for (int i = 0; i < size; i++) {
8984 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8985 for (UriPermission perm : perms.values()) {
8986 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8987 && perm.persistedModeFlags != 0) {
8988 result.add(perm.buildPersistedPublicApiObject());
8993 return new ParceledListSlice<android.content.UriPermission>(result);
8997 public void clearGrantedUriPermissions(String packageName, int userId) {
8998 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8999 "clearGrantedUriPermissions");
9000 removeUriPermissionsForPackageLocked(packageName, userId, true);
9004 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9005 synchronized (this) {
9007 who != null ? getRecordForAppLocked(who) : null;
9008 if (app == null) return;
9010 Message msg = Message.obtain();
9011 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9013 msg.arg1 = waiting ? 1 : 0;
9014 mUiHandler.sendMessage(msg);
9019 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9020 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9021 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9022 outInfo.availMem = Process.getFreeMemory();
9023 outInfo.totalMem = Process.getTotalMemory();
9024 outInfo.threshold = homeAppMem;
9025 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9026 outInfo.hiddenAppThreshold = cachedAppMem;
9027 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9028 ProcessList.SERVICE_ADJ);
9029 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9030 ProcessList.VISIBLE_APP_ADJ);
9031 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9032 ProcessList.FOREGROUND_APP_ADJ);
9035 // =========================================================
9037 // =========================================================
9040 public List<IAppTask> getAppTasks(String callingPackage) {
9041 int callingUid = Binder.getCallingUid();
9042 long ident = Binder.clearCallingIdentity();
9044 synchronized(this) {
9045 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9047 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9049 final int N = mRecentTasks.size();
9050 for (int i = 0; i < N; i++) {
9051 TaskRecord tr = mRecentTasks.get(i);
9052 // Skip tasks that do not match the caller. We don't need to verify
9053 // callingPackage, because we are also limiting to callingUid and know
9054 // that will limit to the correct security sandbox.
9055 if (tr.effectiveUid != callingUid) {
9058 Intent intent = tr.getBaseIntent();
9059 if (intent == null ||
9060 !callingPackage.equals(intent.getComponent().getPackageName())) {
9063 ActivityManager.RecentTaskInfo taskInfo =
9064 createRecentTaskInfoFromTaskRecord(tr);
9065 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9069 Binder.restoreCallingIdentity(ident);
9076 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9077 final int callingUid = Binder.getCallingUid();
9078 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9080 synchronized(this) {
9081 if (DEBUG_ALL) Slog.v(
9082 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9084 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9087 // TODO: Improve with MRU list from all ActivityStacks.
9088 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9095 * Creates a new RecentTaskInfo from a TaskRecord.
9097 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9098 // Update the task description to reflect any changes in the task stack
9099 tr.updateTaskDescription();
9101 // Compose the recent task info
9102 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9103 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9104 rti.persistentId = tr.taskId;
9105 rti.baseIntent = new Intent(tr.getBaseIntent());
9106 rti.origActivity = tr.origActivity;
9107 rti.realActivity = tr.realActivity;
9108 rti.description = tr.lastDescription;
9109 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9110 rti.userId = tr.userId;
9111 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9112 rti.firstActiveTime = tr.firstActiveTime;
9113 rti.lastActiveTime = tr.lastActiveTime;
9114 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9115 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9116 rti.numActivities = 0;
9117 if (tr.mBounds != null) {
9118 rti.bounds = new Rect(tr.mBounds);
9120 rti.isDockable = tr.canGoInDockedStack();
9121 rti.resizeMode = tr.mResizeMode;
9123 ActivityRecord base = null;
9124 ActivityRecord top = null;
9127 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9128 tmp = tr.mActivities.get(i);
9129 if (tmp.finishing) {
9133 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9136 rti.numActivities++;
9139 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9140 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9145 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9146 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9147 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9149 if (checkPermission(android.Manifest.permission.GET_TASKS,
9150 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9151 // Temporary compatibility: some existing apps on the system image may
9152 // still be requesting the old permission and not switched to the new
9153 // one; if so, we'll still allow them full access. This means we need
9154 // to see if they are holding the old permission and are a system app.
9156 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9158 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9159 + " is using old GET_TASKS but privileged; allowing");
9161 } catch (RemoteException e) {
9166 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9167 + " does not hold REAL_GET_TASKS; limiting output");
9173 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9175 final int callingUid = Binder.getCallingUid();
9176 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9177 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9179 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9180 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9181 synchronized (this) {
9182 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9184 final boolean detailed = checkCallingPermission(
9185 android.Manifest.permission.GET_DETAILED_TASKS)
9186 == PackageManager.PERMISSION_GRANTED;
9188 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9189 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9190 return ParceledListSlice.emptyList();
9192 mRecentTasks.loadUserRecentsLocked(userId);
9194 final int recentsCount = mRecentTasks.size();
9195 ArrayList<ActivityManager.RecentTaskInfo> res =
9196 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9198 final Set<Integer> includedUsers;
9199 if (includeProfiles) {
9200 includedUsers = mUserController.getProfileIds(userId);
9202 includedUsers = new HashSet<>();
9204 includedUsers.add(Integer.valueOf(userId));
9206 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9207 TaskRecord tr = mRecentTasks.get(i);
9208 // Only add calling user or related users recent tasks
9209 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9210 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9214 if (tr.realActivitySuspended) {
9215 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9219 // Return the entry if desired by the caller. We always return
9220 // the first entry, because callers always expect this to be the
9221 // foreground app. We may filter others if the caller has
9222 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9223 // we should exclude the entry.
9227 || (tr.intent == null)
9228 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9231 // If the caller doesn't have the GET_TASKS permission, then only
9232 // allow them to see a small subset of tasks -- their own and home.
9233 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9234 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9238 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9239 if (tr.stack != null && tr.stack.isHomeStack()) {
9240 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9241 "Skipping, home stack task: " + tr);
9245 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9246 final ActivityStack stack = tr.stack;
9247 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9248 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9249 "Skipping, top task in docked stack: " + tr);
9253 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9254 if (tr.stack != null && tr.stack.isPinnedStack()) {
9255 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9256 "Skipping, pinned stack task: " + tr);
9260 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9261 // Don't include auto remove tasks that are finished or finishing.
9262 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9263 "Skipping, auto-remove without activity: " + tr);
9266 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9267 && !tr.isAvailable) {
9268 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9269 "Skipping, unavail real act: " + tr);
9273 if (!tr.mUserSetupComplete) {
9274 // Don't include task launched while user is not done setting-up.
9275 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9276 "Skipping, user setup not complete: " + tr);
9280 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9282 rti.baseIntent.replaceExtras((Bundle)null);
9289 return new ParceledListSlice<>(res);
9294 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9295 synchronized (this) {
9296 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9297 "getTaskThumbnail()");
9298 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9299 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9301 return tr.getTaskThumbnailLocked();
9308 public int addAppTask(IBinder activityToken, Intent intent,
9309 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9310 final int callingUid = Binder.getCallingUid();
9311 final long callingIdent = Binder.clearCallingIdentity();
9314 synchronized (this) {
9315 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9317 throw new IllegalArgumentException("Activity does not exist; token="
9320 ComponentName comp = intent.getComponent();
9322 throw new IllegalArgumentException("Intent " + intent
9323 + " must specify explicit component");
9325 if (thumbnail.getWidth() != mThumbnailWidth
9326 || thumbnail.getHeight() != mThumbnailHeight) {
9327 throw new IllegalArgumentException("Bad thumbnail size: got "
9328 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9329 + mThumbnailWidth + "x" + mThumbnailHeight);
9331 if (intent.getSelector() != null) {
9332 intent.setSelector(null);
9334 if (intent.getSourceBounds() != null) {
9335 intent.setSourceBounds(null);
9337 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9338 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9339 // The caller has added this as an auto-remove task... that makes no
9340 // sense, so turn off auto-remove.
9341 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9344 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9345 mLastAddedTaskActivity = null;
9347 ActivityInfo ainfo = mLastAddedTaskActivity;
9348 if (ainfo == null) {
9349 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9350 comp, 0, UserHandle.getUserId(callingUid));
9351 if (ainfo.applicationInfo.uid != callingUid) {
9352 throw new SecurityException(
9353 "Can't add task for another application: target uid="
9354 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9358 // Use the full screen as the context for the task thumbnail
9359 final Point displaySize = new Point();
9360 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9361 r.task.stack.getDisplaySize(displaySize);
9362 thumbnailInfo.taskWidth = displaySize.x;
9363 thumbnailInfo.taskHeight = displaySize.y;
9364 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9366 TaskRecord task = new TaskRecord(this,
9367 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9368 ainfo, intent, description, thumbnailInfo);
9370 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9372 // If this would have caused a trim, then we'll abort because that
9373 // means it would be added at the end of the list but then just removed.
9374 return INVALID_TASK_ID;
9377 final int N = mRecentTasks.size();
9378 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9379 final TaskRecord tr = mRecentTasks.remove(N - 1);
9380 tr.removedFromRecents();
9383 task.inRecents = true;
9384 mRecentTasks.add(task);
9385 r.task.stack.addTask(task, false, "addAppTask");
9387 task.setLastThumbnailLocked(thumbnail);
9388 task.freeLastThumbnail();
9393 Binder.restoreCallingIdentity(callingIdent);
9398 public Point getAppTaskThumbnailSize() {
9399 synchronized (this) {
9400 return new Point(mThumbnailWidth, mThumbnailHeight);
9405 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9406 synchronized (this) {
9407 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9409 r.setTaskDescription(td);
9410 r.task.updateTaskDescription();
9416 public void setTaskResizeable(int taskId, int resizeableMode) {
9417 synchronized (this) {
9418 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9419 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9421 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9424 if (task.mResizeMode != resizeableMode) {
9425 task.mResizeMode = resizeableMode;
9426 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9427 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9428 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9434 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9435 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9436 long ident = Binder.clearCallingIdentity();
9438 synchronized (this) {
9439 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9441 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9444 int stackId = task.stack.mStackId;
9445 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9446 // in crop windows resize mode or if the task size is affected by the docked stack
9447 // changing size. No need to update configuration.
9448 if (bounds != null && task.inCropWindowsResizeMode()
9449 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9450 mWindowManager.scrollTask(task.taskId, bounds);
9454 // Place the task in the right stack if it isn't there already based on
9455 // the requested bounds.
9456 // The stack transition logic is:
9457 // - a null bounds on a freeform task moves that task to fullscreen
9458 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9459 // that task to freeform
9460 // - otherwise the task is not moved
9461 if (!StackId.isTaskResizeAllowed(stackId)) {
9462 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9464 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9465 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9466 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9467 stackId = FREEFORM_WORKSPACE_STACK_ID;
9469 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9470 if (stackId != task.stack.mStackId) {
9471 mStackSupervisor.moveTaskToStackUncheckedLocked(
9472 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9473 preserveWindow = false;
9476 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9477 false /* deferResume */);
9480 Binder.restoreCallingIdentity(ident);
9485 public Rect getTaskBounds(int taskId) {
9486 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9487 long ident = Binder.clearCallingIdentity();
9488 Rect rect = new Rect();
9490 synchronized (this) {
9491 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9492 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9494 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9497 if (task.stack != null) {
9498 // Return the bounds from window manager since it will be adjusted for various
9499 // things like the presense of a docked stack for tasks that aren't resizeable.
9500 mWindowManager.getTaskBounds(task.taskId, rect);
9502 // Task isn't in window manager yet since it isn't associated with a stack.
9503 // Return the persist value from activity manager
9504 if (task.mBounds != null) {
9505 rect.set(task.mBounds);
9506 } else if (task.mLastNonFullscreenBounds != null) {
9507 rect.set(task.mLastNonFullscreenBounds);
9512 Binder.restoreCallingIdentity(ident);
9518 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9519 if (userId != UserHandle.getCallingUserId()) {
9520 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9521 "getTaskDescriptionIcon");
9523 final File passedIconFile = new File(filePath);
9524 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9525 passedIconFile.getName());
9526 if (!legitIconFile.getPath().equals(filePath)
9527 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9528 throw new IllegalArgumentException("Bad file path: " + filePath
9529 + " passed for userId " + userId);
9531 return mRecentTasks.getTaskDescriptionIcon(filePath);
9535 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9536 throws RemoteException {
9537 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9538 opts.getCustomInPlaceResId() == 0) {
9539 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9540 "with valid animation");
9542 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9543 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9544 opts.getCustomInPlaceResId());
9545 mWindowManager.executeAppTransition();
9548 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9549 boolean removeFromRecents) {
9550 if (removeFromRecents) {
9551 mRecentTasks.remove(tr);
9552 tr.removedFromRecents();
9554 ComponentName component = tr.getBaseIntent().getComponent();
9555 if (component == null) {
9556 Slog.w(TAG, "No component for base intent of task: " + tr);
9560 // Find any running services associated with this app and stop if needed.
9561 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9567 // Determine if the process(es) for this task should be killed.
9568 final String pkg = component.getPackageName();
9569 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9570 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9571 for (int i = 0; i < pmap.size(); i++) {
9573 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9574 for (int j = 0; j < uids.size(); j++) {
9575 ProcessRecord proc = uids.valueAt(j);
9576 if (proc.userId != tr.userId) {
9577 // Don't kill process for a different user.
9580 if (proc == mHomeProcess) {
9581 // Don't kill the home process along with tasks from the same package.
9584 if (!proc.pkgList.containsKey(pkg)) {
9585 // Don't kill process that is not associated with this task.
9589 for (int k = 0; k < proc.activities.size(); k++) {
9590 TaskRecord otherTask = proc.activities.get(k).task;
9591 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9592 // Don't kill process(es) that has an activity in a different task that is
9598 if (proc.foregroundServices) {
9599 // Don't kill process(es) with foreground service.
9603 // Add process to kill list.
9604 procsToKill.add(proc);
9608 // Kill the running processes.
9609 for (int i = 0; i < procsToKill.size(); i++) {
9610 ProcessRecord pr = procsToKill.get(i);
9611 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9612 && pr.curReceiver == null) {
9613 pr.kill("remove task", true);
9615 // We delay killing processes that are not in the background or running a receiver.
9616 pr.waitingToKill = "remove task";
9621 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9622 // Remove all tasks with activities in the specified package from the list of recent tasks
9623 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9624 TaskRecord tr = mRecentTasks.get(i);
9625 if (tr.userId != userId) continue;
9627 ComponentName cn = tr.intent.getComponent();
9628 if (cn != null && cn.getPackageName().equals(packageName)) {
9629 // If the package name matches, remove the task.
9630 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9635 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9638 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9639 TaskRecord tr = mRecentTasks.get(i);
9640 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9644 ComponentName cn = tr.intent.getComponent();
9645 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9646 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9647 if (sameComponent) {
9648 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9654 * Removes the task with the specified task id.
9656 * @param taskId Identifier of the task to be removed.
9657 * @param killProcess Kill any process associated with the task if possible.
9658 * @param removeFromRecents Whether to also remove the task from recents.
9659 * @return Returns true if the given task was found and removed.
9661 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9662 boolean removeFromRecents) {
9663 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9664 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9666 tr.removeTaskActivitiesLocked();
9667 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9668 if (tr.isPersistable) {
9669 notifyTaskPersisterLocked(null, true);
9673 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9678 public void removeStack(int stackId) {
9679 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9680 if (stackId == HOME_STACK_ID) {
9681 throw new IllegalArgumentException("Removing home stack is not allowed.");
9684 synchronized (this) {
9685 final long ident = Binder.clearCallingIdentity();
9687 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9688 if (stack == null) {
9691 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9692 for (int i = tasks.size() - 1; i >= 0; i--) {
9693 removeTaskByIdLocked(
9694 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9697 Binder.restoreCallingIdentity(ident);
9703 public boolean removeTask(int taskId) {
9704 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9705 synchronized (this) {
9706 final long ident = Binder.clearCallingIdentity();
9708 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9710 Binder.restoreCallingIdentity(ident);
9716 * TODO: Add mController hook
9719 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9720 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9722 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9723 synchronized(this) {
9724 moveTaskToFrontLocked(taskId, flags, bOptions);
9728 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9729 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9731 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9732 Binder.getCallingUid(), -1, -1, "Task to front")) {
9733 ActivityOptions.abort(options);
9736 final long origId = Binder.clearCallingIdentity();
9738 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9740 Slog.d(TAG, "Could not find task for id: "+ taskId);
9743 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9744 mStackSupervisor.showLockTaskToast();
9745 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9748 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9749 if (prev != null && prev.isRecentsActivity()) {
9750 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9752 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9753 false /* forceNonResizable */);
9755 Binder.restoreCallingIdentity(origId);
9757 ActivityOptions.abort(options);
9761 * Moves an activity, and all of the other activities within the same task, to the bottom
9762 * of the history stack. The activity's order within the task is unchanged.
9764 * @param token A reference to the activity we wish to move
9765 * @param nonRoot If false then this only works if the activity is the root
9766 * of a task; if true it will work for any activity in a task.
9767 * @return Returns true if the move completed, false if not.
9770 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9771 enforceNotIsolatedCaller("moveActivityTaskToBack");
9772 synchronized(this) {
9773 final long origId = Binder.clearCallingIdentity();
9775 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9776 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9778 if (mStackSupervisor.isLockedTask(task)) {
9779 mStackSupervisor.showLockTaskToast();
9782 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9785 Binder.restoreCallingIdentity(origId);
9792 public void moveTaskBackwards(int task) {
9793 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9794 "moveTaskBackwards()");
9796 synchronized(this) {
9797 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9798 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9801 final long origId = Binder.clearCallingIdentity();
9802 moveTaskBackwardsLocked(task);
9803 Binder.restoreCallingIdentity(origId);
9807 private final void moveTaskBackwardsLocked(int task) {
9808 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9812 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9813 IActivityContainerCallback callback) throws RemoteException {
9814 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9815 synchronized (this) {
9816 if (parentActivityToken == null) {
9817 throw new IllegalArgumentException("parent token must not be null");
9819 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9823 if (callback == null) {
9824 throw new IllegalArgumentException("callback must not be null");
9826 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9831 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9832 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9833 synchronized (this) {
9834 mStackSupervisor.deleteActivityContainer(container);
9839 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9840 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9841 synchronized (this) {
9842 final int stackId = mStackSupervisor.getNextStackId();
9843 final ActivityStack stack =
9844 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9845 if (stack == null) {
9848 return stack.mActivityContainer;
9853 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9854 synchronized (this) {
9855 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9856 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9857 return stack.mActivityContainer.getDisplayId();
9859 return Display.DEFAULT_DISPLAY;
9864 public int getActivityStackId(IBinder token) throws RemoteException {
9865 synchronized (this) {
9866 ActivityStack stack = ActivityRecord.getStackLocked(token);
9867 if (stack == null) {
9868 return INVALID_STACK_ID;
9870 return stack.mStackId;
9875 public void exitFreeformMode(IBinder token) throws RemoteException {
9876 synchronized (this) {
9877 long ident = Binder.clearCallingIdentity();
9879 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9881 throw new IllegalArgumentException(
9882 "exitFreeformMode: No activity record matching token=" + token);
9884 final ActivityStack stack = r.getStackLocked(token);
9885 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9886 throw new IllegalStateException(
9887 "exitFreeformMode: You can only go fullscreen from freeform.");
9889 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9890 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9891 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9893 Binder.restoreCallingIdentity(ident);
9899 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9900 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9901 if (stackId == HOME_STACK_ID) {
9902 throw new IllegalArgumentException(
9903 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9905 synchronized (this) {
9906 long ident = Binder.clearCallingIdentity();
9908 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9909 + " to stackId=" + stackId + " toTop=" + toTop);
9910 if (stackId == DOCKED_STACK_ID) {
9911 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9912 null /* initialBounds */);
9914 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9915 !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9916 if (result && stackId == DOCKED_STACK_ID) {
9917 // If task moved to docked stack - show recents if needed.
9918 mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9919 "moveTaskToDockedStack");
9922 Binder.restoreCallingIdentity(ident);
9928 public void swapDockedAndFullscreenStack() throws RemoteException {
9929 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9930 synchronized (this) {
9931 long ident = Binder.clearCallingIdentity();
9933 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9934 FULLSCREEN_WORKSPACE_STACK_ID);
9935 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9937 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9938 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9940 if (topTask == null || tasks == null || tasks.size() == 0) {
9942 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9946 // TODO: App transition
9947 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9949 // Defer the resume so resume/pausing while moving stacks is dangerous.
9950 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9951 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9952 ANIMATE, true /* deferResume */);
9953 final int size = tasks.size();
9954 for (int i = 0; i < size; i++) {
9955 final int id = tasks.get(i).taskId;
9956 if (id == topTask.taskId) {
9959 mStackSupervisor.moveTaskToStackLocked(id,
9960 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9961 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9964 // Because we deferred the resume, to avoid conflicts with stack switches while
9965 // resuming, we need to do it after all the tasks are moved.
9966 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9967 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9969 mWindowManager.executeAppTransition();
9971 Binder.restoreCallingIdentity(ident);
9977 * Moves the input task to the docked stack.
9979 * @param taskId Id of task to move.
9980 * @param createMode The mode the docked stack should be created in if it doesn't exist
9982 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9984 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9985 * @param toTop If the task and stack should be moved to the top.
9986 * @param animate Whether we should play an animation for the moving the task
9987 * @param initialBounds If the docked stack gets created, it will use these bounds for the
9988 * docked stack. Pass {@code null} to use default bounds.
9991 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9992 Rect initialBounds, boolean moveHomeStackFront) {
9993 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9994 synchronized (this) {
9995 long ident = Binder.clearCallingIdentity();
9997 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9998 + " to createMode=" + createMode + " toTop=" + toTop);
9999 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10000 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10001 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10002 animate, DEFER_RESUME);
10004 if (moveHomeStackFront) {
10005 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10007 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10011 Binder.restoreCallingIdentity(ident);
10017 * Moves the top activity in the input stackId to the pinned stack.
10019 * @param stackId Id of stack to move the top activity to pinned stack.
10020 * @param bounds Bounds to use for pinned stack.
10022 * @return True if the top activity of the input stack was successfully moved to the pinned
10026 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10027 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10028 synchronized (this) {
10029 if (!mSupportsPictureInPicture) {
10030 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10031 + "Device doesn't support picture-in-pciture mode");
10034 long ident = Binder.clearCallingIdentity();
10036 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10038 Binder.restoreCallingIdentity(ident);
10044 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10045 boolean preserveWindows, boolean animate, int animationDuration) {
10046 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10047 long ident = Binder.clearCallingIdentity();
10049 synchronized (this) {
10051 if (stackId == PINNED_STACK_ID) {
10052 mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10054 throw new IllegalArgumentException("Stack: " + stackId
10055 + " doesn't support animated resize.");
10058 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10059 null /* tempTaskInsetBounds */, preserveWindows,
10060 allowResizeInDockedMode, !DEFER_RESUME);
10064 Binder.restoreCallingIdentity(ident);
10069 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10070 Rect tempDockedTaskInsetBounds,
10071 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10072 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10073 "resizeDockedStack()");
10074 long ident = Binder.clearCallingIdentity();
10076 synchronized (this) {
10077 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10078 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10082 Binder.restoreCallingIdentity(ident);
10087 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10088 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10089 "resizePinnedStack()");
10090 final long ident = Binder.clearCallingIdentity();
10092 synchronized (this) {
10093 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10096 Binder.restoreCallingIdentity(ident);
10101 public void positionTaskInStack(int taskId, int stackId, int position) {
10102 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10103 if (stackId == HOME_STACK_ID) {
10104 throw new IllegalArgumentException(
10105 "positionTaskInStack: Attempt to change the position of task "
10106 + taskId + " in/to home stack");
10108 synchronized (this) {
10109 long ident = Binder.clearCallingIdentity();
10111 if (DEBUG_STACK) Slog.d(TAG_STACK,
10112 "positionTaskInStack: positioning task=" + taskId
10113 + " in stackId=" + stackId + " at position=" + position);
10114 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10116 Binder.restoreCallingIdentity(ident);
10122 public List<StackInfo> getAllStackInfos() {
10123 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10124 long ident = Binder.clearCallingIdentity();
10126 synchronized (this) {
10127 return mStackSupervisor.getAllStackInfosLocked();
10130 Binder.restoreCallingIdentity(ident);
10135 public StackInfo getStackInfo(int stackId) {
10136 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10137 long ident = Binder.clearCallingIdentity();
10139 synchronized (this) {
10140 return mStackSupervisor.getStackInfoLocked(stackId);
10143 Binder.restoreCallingIdentity(ident);
10148 public boolean isInHomeStack(int taskId) {
10149 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10150 long ident = Binder.clearCallingIdentity();
10152 synchronized (this) {
10153 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10154 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10155 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10158 Binder.restoreCallingIdentity(ident);
10163 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10164 synchronized(this) {
10165 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10170 public void updateDeviceOwner(String packageName) {
10171 final int callingUid = Binder.getCallingUid();
10172 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10173 throw new SecurityException("updateDeviceOwner called from non-system process");
10175 synchronized (this) {
10176 mDeviceOwnerName = packageName;
10181 public void updateLockTaskPackages(int userId, String[] packages) {
10182 final int callingUid = Binder.getCallingUid();
10183 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10184 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10185 "updateLockTaskPackages()");
10187 synchronized (this) {
10188 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10189 Arrays.toString(packages));
10190 mLockTaskPackages.put(userId, packages);
10191 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10196 void startLockTaskModeLocked(TaskRecord task) {
10197 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10198 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10202 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10203 // is initiated by system after the pinning request was shown and locked mode is initiated
10204 // by an authorized app directly
10205 final int callingUid = Binder.getCallingUid();
10206 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10207 long ident = Binder.clearCallingIdentity();
10209 if (!isSystemInitiated) {
10210 task.mLockTaskUid = callingUid;
10211 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10212 // startLockTask() called by app and task mode is lockTaskModeDefault.
10213 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10214 StatusBarManagerInternal statusBarManager =
10215 LocalServices.getService(StatusBarManagerInternal.class);
10216 if (statusBarManager != null) {
10217 statusBarManager.showScreenPinningRequest(task.taskId);
10222 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10223 if (stack == null || task != stack.topTask()) {
10224 throw new IllegalArgumentException("Invalid task, not in foreground");
10227 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10229 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10230 ActivityManager.LOCK_TASK_MODE_PINNED :
10231 ActivityManager.LOCK_TASK_MODE_LOCKED,
10232 "startLockTask", true);
10234 Binder.restoreCallingIdentity(ident);
10239 public void startLockTaskMode(int taskId) {
10240 synchronized (this) {
10241 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10242 if (task != null) {
10243 startLockTaskModeLocked(task);
10249 public void startLockTaskMode(IBinder token) {
10250 synchronized (this) {
10251 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10255 final TaskRecord task = r.task;
10256 if (task != null) {
10257 startLockTaskModeLocked(task);
10263 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10264 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10265 // This makes inner call to look as if it was initiated by system.
10266 long ident = Binder.clearCallingIdentity();
10268 synchronized (this) {
10269 startLockTaskMode(taskId);
10272 Binder.restoreCallingIdentity(ident);
10277 public void stopLockTaskMode() {
10278 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10279 if (lockTask == null) {
10280 // Our work here is done.
10284 final int callingUid = Binder.getCallingUid();
10285 final int lockTaskUid = lockTask.mLockTaskUid;
10286 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10287 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10291 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10292 // It is possible lockTaskMode was started by the system process because
10293 // android:lockTaskMode is set to a locking value in the application manifest
10294 // instead of the app calling startLockTaskMode. In this case
10295 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10296 // {@link TaskRecord.effectiveUid} instead. Also caller with
10297 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10298 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10299 && callingUid != lockTaskUid
10300 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10301 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10302 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10305 long ident = Binder.clearCallingIdentity();
10307 Log.d(TAG, "stopLockTaskMode");
10309 synchronized (this) {
10310 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10311 "stopLockTask", true);
10313 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10315 tm.showInCallScreen(false);
10318 Binder.restoreCallingIdentity(ident);
10323 * This API should be called by SystemUI only when user perform certain action to dismiss
10324 * lock task mode. We should only dismiss pinned lock task mode in this case.
10327 public void stopSystemLockTaskMode() throws RemoteException {
10328 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10329 stopLockTaskMode();
10331 mStackSupervisor.showLockTaskToast();
10336 public boolean isInLockTaskMode() {
10337 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10341 public int getLockTaskModeState() {
10342 synchronized (this) {
10343 return mStackSupervisor.getLockTaskModeState();
10348 public void showLockTaskEscapeMessage(IBinder token) {
10349 synchronized (this) {
10350 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10354 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10358 // =========================================================
10359 // CONTENT PROVIDERS
10360 // =========================================================
10362 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10363 List<ProviderInfo> providers = null;
10365 providers = AppGlobals.getPackageManager()
10366 .queryContentProviders(app.processName, app.uid,
10367 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10368 | MATCH_DEBUG_TRIAGED_MISSING)
10370 } catch (RemoteException ex) {
10372 if (DEBUG_MU) Slog.v(TAG_MU,
10373 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10374 int userId = app.userId;
10375 if (providers != null) {
10376 int N = providers.size();
10377 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10378 for (int i=0; i<N; i++) {
10379 // TODO: keep logic in sync with installEncryptionUnawareProviders
10381 (ProviderInfo)providers.get(i);
10382 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10383 cpi.name, cpi.flags);
10384 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10385 // This is a singleton provider, but a user besides the
10386 // default user is asking to initialize a process it runs
10387 // in... well, no, it doesn't actually run in this process,
10388 // it runs in the process of the default user. Get rid of it.
10389 providers.remove(i);
10395 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10396 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10398 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10399 mProviderMap.putProviderByClass(comp, cpr);
10401 if (DEBUG_MU) Slog.v(TAG_MU,
10402 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10403 app.pubProviders.put(cpi.name, cpr);
10404 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10405 // Don't add this if it is a platform component that is marked
10406 // to run in multiple processes, because this is actually
10407 // part of the framework so doesn't make sense to track as a
10408 // separate apk in the process.
10409 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10412 notifyPackageUse(cpi.applicationInfo.packageName,
10413 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10420 * Check if the calling UID has a possible chance at accessing the provider
10421 * at the given authority and user.
10423 public String checkContentProviderAccess(String authority, int userId) {
10424 if (userId == UserHandle.USER_ALL) {
10425 mContext.enforceCallingOrSelfPermission(
10426 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10427 userId = UserHandle.getCallingUserId();
10430 ProviderInfo cpi = null;
10432 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10433 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10434 | PackageManager.MATCH_DIRECT_BOOT_AWARE
10435 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10437 } catch (RemoteException ignored) {
10440 // TODO: make this an outright failure in a future platform release;
10441 // until then anonymous content notifications are unprotected
10442 //return "Failed to find provider " + authority + " for user " + userId;
10446 ProcessRecord r = null;
10447 synchronized (mPidsSelfLocked) {
10448 r = mPidsSelfLocked.get(Binder.getCallingPid());
10451 return "Failed to find PID " + Binder.getCallingPid();
10454 synchronized (this) {
10455 return checkContentProviderPermissionLocked(cpi, r, userId, true);
10460 * Check if {@link ProcessRecord} has a possible chance at accessing the
10461 * given {@link ProviderInfo}. Final permission checking is always done
10462 * in {@link ContentProvider}.
10464 private final String checkContentProviderPermissionLocked(
10465 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10466 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10467 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10468 boolean checkedGrants = false;
10470 // Looking for cross-user grants before enforcing the typical cross-users permissions
10471 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10472 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10473 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10476 checkedGrants = true;
10478 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10479 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10480 if (userId != tmpTargetUserId) {
10481 // When we actually went to determine the final targer user ID, this ended
10482 // up different than our initial check for the authority. This is because
10483 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10484 // SELF. So we need to re-check the grants again.
10485 checkedGrants = false;
10488 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10489 cpi.applicationInfo.uid, cpi.exported)
10490 == PackageManager.PERMISSION_GRANTED) {
10493 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10494 cpi.applicationInfo.uid, cpi.exported)
10495 == PackageManager.PERMISSION_GRANTED) {
10499 PathPermission[] pps = cpi.pathPermissions;
10501 int i = pps.length;
10504 PathPermission pp = pps[i];
10505 String pprperm = pp.getReadPermission();
10506 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10507 cpi.applicationInfo.uid, cpi.exported)
10508 == PackageManager.PERMISSION_GRANTED) {
10511 String ppwperm = pp.getWritePermission();
10512 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10513 cpi.applicationInfo.uid, cpi.exported)
10514 == PackageManager.PERMISSION_GRANTED) {
10519 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10524 if (!cpi.exported) {
10525 msg = "Permission Denial: opening provider " + cpi.name
10526 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10527 + ", uid=" + callingUid + ") that is not exported from uid "
10528 + cpi.applicationInfo.uid;
10530 msg = "Permission Denial: opening provider " + cpi.name
10531 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10532 + ", uid=" + callingUid + ") requires "
10533 + cpi.readPermission + " or " + cpi.writePermission;
10540 * Returns if the ContentProvider has granted a uri to callingUid
10542 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10543 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10544 if (perms != null) {
10545 for (int i=perms.size()-1; i>=0; i--) {
10546 GrantUri grantUri = perms.keyAt(i);
10547 if (grantUri.sourceUserId == userId || !checkUser) {
10548 if (matchesProvider(grantUri.uri, cpi)) {
10558 * Returns true if the uri authority is one of the authorities specified in the provider.
10560 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10561 String uriAuth = uri.getAuthority();
10562 String cpiAuth = cpi.authority;
10563 if (cpiAuth.indexOf(';') == -1) {
10564 return cpiAuth.equals(uriAuth);
10566 String[] cpiAuths = cpiAuth.split(";");
10567 int length = cpiAuths.length;
10568 for (int i = 0; i < length; i++) {
10569 if (cpiAuths[i].equals(uriAuth)) return true;
10574 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10575 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10577 for (int i=0; i<r.conProviders.size(); i++) {
10578 ContentProviderConnection conn = r.conProviders.get(i);
10579 if (conn.provider == cpr) {
10580 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10581 "Adding provider requested by "
10582 + r.processName + " from process "
10583 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10584 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10586 conn.stableCount++;
10587 conn.numStableIncs++;
10589 conn.unstableCount++;
10590 conn.numUnstableIncs++;
10595 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10597 conn.stableCount = 1;
10598 conn.numStableIncs = 1;
10600 conn.unstableCount = 1;
10601 conn.numUnstableIncs = 1;
10603 cpr.connections.add(conn);
10604 r.conProviders.add(conn);
10605 startAssociationLocked(r.uid, r.processName, r.curProcState,
10606 cpr.uid, cpr.name, cpr.info.processName);
10609 cpr.addExternalProcessHandleLocked(externalProcessToken);
10613 boolean decProviderCountLocked(ContentProviderConnection conn,
10614 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10615 if (conn != null) {
10616 cpr = conn.provider;
10617 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10618 "Removing provider requested by "
10619 + conn.client.processName + " from process "
10620 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10621 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10623 conn.stableCount--;
10625 conn.unstableCount--;
10627 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10628 cpr.connections.remove(conn);
10629 conn.client.conProviders.remove(conn);
10630 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10631 // The client is more important than last activity -- note the time this
10632 // is happening, so we keep the old provider process around a bit as last
10633 // activity to avoid thrashing it.
10634 if (cpr.proc != null) {
10635 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10638 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10643 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10647 private void checkTime(long startTime, String where) {
10648 long now = SystemClock.uptimeMillis();
10649 if ((now-startTime) > 50) {
10650 // If we are taking more than 50ms, log about it.
10651 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10655 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10657 PROC_SPACE_TERM|PROC_PARENS,
10658 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
10661 private final long[] mProcessStateStatsLongs = new long[1];
10663 boolean isProcessAliveLocked(ProcessRecord proc) {
10664 if (proc.procStatFile == null) {
10665 proc.procStatFile = "/proc/" + proc.pid + "/stat";
10667 mProcessStateStatsLongs[0] = 0;
10668 if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10669 mProcessStateStatsLongs, null)) {
10670 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10673 final long state = mProcessStateStatsLongs[0];
10674 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10676 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10679 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10680 String name, IBinder token, boolean stable, int userId) {
10681 ContentProviderRecord cpr;
10682 ContentProviderConnection conn = null;
10683 ProviderInfo cpi = null;
10685 synchronized(this) {
10686 long startTime = SystemClock.uptimeMillis();
10688 ProcessRecord r = null;
10689 if (caller != null) {
10690 r = getRecordForAppLocked(caller);
10692 throw new SecurityException(
10693 "Unable to find app for caller " + caller
10694 + " (pid=" + Binder.getCallingPid()
10695 + ") when getting content provider " + name);
10699 boolean checkCrossUser = true;
10701 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10703 // First check if this content provider has been published...
10704 cpr = mProviderMap.getProviderByName(name, userId);
10705 // If that didn't work, check if it exists for user 0 and then
10706 // verify that it's a singleton provider before using it.
10707 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10708 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10711 if (isSingleton(cpi.processName, cpi.applicationInfo,
10712 cpi.name, cpi.flags)
10713 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10714 userId = UserHandle.USER_SYSTEM;
10715 checkCrossUser = false;
10723 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10724 if (providerRunning) {
10727 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10728 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10730 throw new SecurityException(msg);
10732 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10734 if (r != null && cpr.canRunHere(r)) {
10735 // This provider has been published or is in the process
10736 // of being published... but it is also allowed to run
10737 // in the caller's process, so don't make a connection
10738 // and just let the caller instantiate its own instance.
10739 ContentProviderHolder holder = cpr.newHolder(null);
10740 // don't give caller the provider object, it needs
10741 // to make its own.
10742 holder.provider = null;
10746 final long origId = Binder.clearCallingIdentity();
10748 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10750 // In this case the provider instance already exists, so we can
10751 // return it right away.
10752 conn = incProviderCountLocked(r, cpr, token, stable);
10753 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10754 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10755 // If this is a perceptible app accessing the provider,
10756 // make sure to count it as being accessed and thus
10757 // back up on the LRU list. This is good because
10758 // content providers are often expensive to start.
10759 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10760 updateLruProcessLocked(cpr.proc, false, null);
10761 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10765 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10766 final int verifiedAdj = cpr.proc.verifiedAdj;
10767 boolean success = updateOomAdjLocked(cpr.proc);
10768 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10769 // if the process has been successfully adjusted. So to reduce races with
10770 // it, we will check whether the process still exists. Note that this doesn't
10771 // completely get rid of races with LMK killing the process, but should make
10772 // them much smaller.
10773 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10776 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10777 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10778 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10779 // NOTE: there is still a race here where a signal could be
10780 // pending on the process even though we managed to update its
10781 // adj level. Not sure what to do about this, but at least
10782 // the race is now smaller.
10784 // Uh oh... it looks like the provider's process
10785 // has been killed on us. We need to wait for a new
10786 // process to be started, and make sure its death
10787 // doesn't kill our process.
10788 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10789 + " is crashing; detaching " + r);
10790 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10791 checkTime(startTime, "getContentProviderImpl: before appDied");
10792 appDiedLocked(cpr.proc);
10793 checkTime(startTime, "getContentProviderImpl: after appDied");
10795 // This wasn't the last ref our process had on
10796 // the provider... we have now been killed, bail.
10799 providerRunning = false;
10802 cpr.proc.verifiedAdj = cpr.proc.setAdj;
10805 Binder.restoreCallingIdentity(origId);
10808 if (!providerRunning) {
10810 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10811 cpi = AppGlobals.getPackageManager().
10812 resolveContentProvider(name,
10813 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10814 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10815 } catch (RemoteException ex) {
10820 // If the provider is a singleton AND
10821 // (it's a call within the same user || the provider is a
10823 // Then allow connecting to the singleton provider
10824 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10825 cpi.name, cpi.flags)
10826 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10828 userId = UserHandle.USER_SYSTEM;
10830 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10831 checkTime(startTime, "getContentProviderImpl: got app info for user");
10834 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10835 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10837 throw new SecurityException(msg);
10839 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10841 if (!mProcessesReady
10842 && !cpi.processName.equals("system")) {
10843 // If this content provider does not run in the system
10844 // process, and the system is not yet ready to run other
10845 // processes, then fail fast instead of hanging.
10846 throw new IllegalArgumentException(
10847 "Attempt to launch content provider before system ready");
10850 // Make sure that the user who owns this provider is running. If not,
10851 // we don't want to allow it to run.
10852 if (!mUserController.isUserRunningLocked(userId, 0)) {
10853 Slog.w(TAG, "Unable to launch app "
10854 + cpi.applicationInfo.packageName + "/"
10855 + cpi.applicationInfo.uid + " for provider "
10856 + name + ": user " + userId + " is stopped");
10860 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10861 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10862 cpr = mProviderMap.getProviderByClass(comp, userId);
10863 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10864 final boolean firstClass = cpr == null;
10866 final long ident = Binder.clearCallingIdentity();
10868 // If permissions need a review before any of the app components can run,
10869 // we return no provider and launch a review activity if the calling app
10870 // is in the foreground.
10871 if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10872 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10878 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10879 ApplicationInfo ai =
10880 AppGlobals.getPackageManager().
10881 getApplicationInfo(
10882 cpi.applicationInfo.packageName,
10883 STOCK_PM_FLAGS, userId);
10884 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10886 Slog.w(TAG, "No package info for content provider "
10890 ai = getAppInfoForUser(ai, userId);
10891 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10892 } catch (RemoteException ex) {
10893 // pm is in same process, this will never happen.
10895 Binder.restoreCallingIdentity(ident);
10899 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10901 if (r != null && cpr.canRunHere(r)) {
10902 // If this is a multiprocess provider, then just return its
10903 // info and allow the caller to instantiate it. Only do
10904 // this if the provider is the same user as the caller's
10905 // process, or can run as root (so can be in any process).
10906 return cpr.newHolder(null);
10909 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10910 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10911 + cpr.info.name + " callers=" + Debug.getCallers(6));
10913 // This is single process, and our app is now connecting to it.
10914 // See if we are already in the process of launching this
10916 final int N = mLaunchingProviders.size();
10918 for (i = 0; i < N; i++) {
10919 if (mLaunchingProviders.get(i) == cpr) {
10924 // If the provider is not already being launched, then get it
10927 final long origId = Binder.clearCallingIdentity();
10930 // Content provider is now in use, its package can't be stopped.
10932 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10933 AppGlobals.getPackageManager().setPackageStoppedState(
10934 cpr.appInfo.packageName, false, userId);
10935 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10936 } catch (RemoteException e) {
10937 } catch (IllegalArgumentException e) {
10938 Slog.w(TAG, "Failed trying to unstop package "
10939 + cpr.appInfo.packageName + ": " + e);
10942 // Use existing process if already started
10943 checkTime(startTime, "getContentProviderImpl: looking for process record");
10944 ProcessRecord proc = getProcessRecordLocked(
10945 cpi.processName, cpr.appInfo.uid, false);
10946 if (proc != null && proc.thread != null && !proc.killed) {
10947 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10948 "Installing in existing process " + proc);
10949 if (!proc.pubProviders.containsKey(cpi.name)) {
10950 checkTime(startTime, "getContentProviderImpl: scheduling install");
10951 proc.pubProviders.put(cpi.name, cpr);
10953 proc.thread.scheduleInstallProvider(cpi);
10954 } catch (RemoteException e) {
10958 checkTime(startTime, "getContentProviderImpl: before start process");
10959 proc = startProcessLocked(cpi.processName,
10960 cpr.appInfo, false, 0, "content provider",
10961 new ComponentName(cpi.applicationInfo.packageName,
10962 cpi.name), false, false, false);
10963 checkTime(startTime, "getContentProviderImpl: after start process");
10964 if (proc == null) {
10965 Slog.w(TAG, "Unable to launch app "
10966 + cpi.applicationInfo.packageName + "/"
10967 + cpi.applicationInfo.uid + " for provider "
10968 + name + ": process is bad");
10972 cpr.launchingApp = proc;
10973 mLaunchingProviders.add(cpr);
10975 Binder.restoreCallingIdentity(origId);
10979 checkTime(startTime, "getContentProviderImpl: updating data structures");
10981 // Make sure the provider is published (the same provider class
10982 // may be published under multiple names).
10984 mProviderMap.putProviderByClass(comp, cpr);
10987 mProviderMap.putProviderByName(name, cpr);
10988 conn = incProviderCountLocked(r, cpr, token, stable);
10989 if (conn != null) {
10990 conn.waiting = true;
10993 checkTime(startTime, "getContentProviderImpl: done!");
10996 // Wait for the provider to be published...
10997 synchronized (cpr) {
10998 while (cpr.provider == null) {
10999 if (cpr.launchingApp == null) {
11000 Slog.w(TAG, "Unable to launch app "
11001 + cpi.applicationInfo.packageName + "/"
11002 + cpi.applicationInfo.uid + " for provider "
11003 + name + ": launching app became null");
11004 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11005 UserHandle.getUserId(cpi.applicationInfo.uid),
11006 cpi.applicationInfo.packageName,
11007 cpi.applicationInfo.uid, name);
11011 if (DEBUG_MU) Slog.v(TAG_MU,
11012 "Waiting to start provider " + cpr
11013 + " launchingApp=" + cpr.launchingApp);
11014 if (conn != null) {
11015 conn.waiting = true;
11018 } catch (InterruptedException ex) {
11020 if (conn != null) {
11021 conn.waiting = false;
11026 return cpr != null ? cpr.newHolder(conn) : null;
11029 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11030 ProcessRecord r, final int userId) {
11031 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11032 cpi.packageName, userId)) {
11034 final boolean callerForeground = r == null || r.setSchedGroup
11035 != ProcessList.SCHED_GROUP_BACKGROUND;
11037 // Show a permission review UI only for starting from a foreground app
11038 if (!callerForeground) {
11039 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11040 + cpi.packageName + " requires a permissions review");
11044 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11045 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11046 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11047 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11049 if (DEBUG_PERMISSIONS_REVIEW) {
11050 Slog.i(TAG, "u" + userId + " Launching permission review "
11051 + "for package " + cpi.packageName);
11054 final UserHandle userHandle = new UserHandle(userId);
11055 mHandler.post(new Runnable() {
11057 public void run() {
11058 mContext.startActivityAsUser(intent, userHandle);
11068 PackageManagerInternal getPackageManagerInternalLocked() {
11069 if (mPackageManagerInt == null) {
11070 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11072 return mPackageManagerInt;
11076 public final ContentProviderHolder getContentProvider(
11077 IApplicationThread caller, String name, int userId, boolean stable) {
11078 enforceNotIsolatedCaller("getContentProvider");
11079 if (caller == null) {
11080 String msg = "null IApplicationThread when getting content provider "
11083 throw new SecurityException(msg);
11085 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11086 // with cross-user grant.
11087 return getContentProviderImpl(caller, name, null, stable, userId);
11090 public ContentProviderHolder getContentProviderExternal(
11091 String name, int userId, IBinder token) {
11092 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11093 "Do not have permission in call getContentProviderExternal()");
11094 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11095 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11096 return getContentProviderExternalUnchecked(name, token, userId);
11099 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11100 IBinder token, int userId) {
11101 return getContentProviderImpl(null, name, token, true, userId);
11105 * Drop a content provider from a ProcessRecord's bookkeeping
11107 public void removeContentProvider(IBinder connection, boolean stable) {
11108 enforceNotIsolatedCaller("removeContentProvider");
11109 long ident = Binder.clearCallingIdentity();
11111 synchronized (this) {
11112 ContentProviderConnection conn;
11114 conn = (ContentProviderConnection)connection;
11115 } catch (ClassCastException e) {
11116 String msg ="removeContentProvider: " + connection
11117 + " not a ContentProviderConnection";
11119 throw new IllegalArgumentException(msg);
11121 if (conn == null) {
11122 throw new NullPointerException("connection is null");
11124 if (decProviderCountLocked(conn, null, null, stable)) {
11125 updateOomAdjLocked();
11129 Binder.restoreCallingIdentity(ident);
11133 public void removeContentProviderExternal(String name, IBinder token) {
11134 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11135 "Do not have permission in call removeContentProviderExternal()");
11136 int userId = UserHandle.getCallingUserId();
11137 long ident = Binder.clearCallingIdentity();
11139 removeContentProviderExternalUnchecked(name, token, userId);
11141 Binder.restoreCallingIdentity(ident);
11145 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11146 synchronized (this) {
11147 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11149 //remove from mProvidersByClass
11150 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11154 //update content provider record entry info
11155 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11156 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11157 if (localCpr.hasExternalProcessHandles()) {
11158 if (localCpr.removeExternalProcessHandleLocked(token)) {
11159 updateOomAdjLocked();
11161 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11162 + " with no external reference for token: "
11166 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11167 + " with no external references.");
11172 public final void publishContentProviders(IApplicationThread caller,
11173 List<ContentProviderHolder> providers) {
11174 if (providers == null) {
11178 enforceNotIsolatedCaller("publishContentProviders");
11179 synchronized (this) {
11180 final ProcessRecord r = getRecordForAppLocked(caller);
11181 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11183 throw new SecurityException(
11184 "Unable to find app for caller " + caller
11185 + " (pid=" + Binder.getCallingPid()
11186 + ") when publishing content providers");
11189 final long origId = Binder.clearCallingIdentity();
11191 final int N = providers.size();
11192 for (int i = 0; i < N; i++) {
11193 ContentProviderHolder src = providers.get(i);
11194 if (src == null || src.info == null || src.provider == null) {
11197 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11198 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11200 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11201 mProviderMap.putProviderByClass(comp, dst);
11202 String names[] = dst.info.authority.split(";");
11203 for (int j = 0; j < names.length; j++) {
11204 mProviderMap.putProviderByName(names[j], dst);
11207 int launchingCount = mLaunchingProviders.size();
11209 boolean wasInLaunchingProviders = false;
11210 for (j = 0; j < launchingCount; j++) {
11211 if (mLaunchingProviders.get(j) == dst) {
11212 mLaunchingProviders.remove(j);
11213 wasInLaunchingProviders = true;
11218 if (wasInLaunchingProviders) {
11219 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11221 synchronized (dst) {
11222 dst.provider = src.provider;
11226 updateOomAdjLocked(r);
11227 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11228 src.info.authority);
11232 Binder.restoreCallingIdentity(origId);
11236 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11237 ContentProviderConnection conn;
11239 conn = (ContentProviderConnection)connection;
11240 } catch (ClassCastException e) {
11241 String msg ="refContentProvider: " + connection
11242 + " not a ContentProviderConnection";
11244 throw new IllegalArgumentException(msg);
11246 if (conn == null) {
11247 throw new NullPointerException("connection is null");
11250 synchronized (this) {
11252 conn.numStableIncs += stable;
11254 stable = conn.stableCount + stable;
11256 throw new IllegalStateException("stableCount < 0: " + stable);
11259 if (unstable > 0) {
11260 conn.numUnstableIncs += unstable;
11262 unstable = conn.unstableCount + unstable;
11263 if (unstable < 0) {
11264 throw new IllegalStateException("unstableCount < 0: " + unstable);
11267 if ((stable+unstable) <= 0) {
11268 throw new IllegalStateException("ref counts can't go to zero here: stable="
11269 + stable + " unstable=" + unstable);
11271 conn.stableCount = stable;
11272 conn.unstableCount = unstable;
11277 public void unstableProviderDied(IBinder connection) {
11278 ContentProviderConnection conn;
11280 conn = (ContentProviderConnection)connection;
11281 } catch (ClassCastException e) {
11282 String msg ="refContentProvider: " + connection
11283 + " not a ContentProviderConnection";
11285 throw new IllegalArgumentException(msg);
11287 if (conn == null) {
11288 throw new NullPointerException("connection is null");
11291 // Safely retrieve the content provider associated with the connection.
11292 IContentProvider provider;
11293 synchronized (this) {
11294 provider = conn.provider.provider;
11297 if (provider == null) {
11298 // Um, yeah, we're way ahead of you.
11302 // Make sure the caller is being honest with us.
11303 if (provider.asBinder().pingBinder()) {
11304 // Er, no, still looks good to us.
11305 synchronized (this) {
11306 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11307 + " says " + conn + " died, but we don't agree");
11312 // Well look at that! It's dead!
11313 synchronized (this) {
11314 if (conn.provider.provider != provider) {
11315 // But something changed... good enough.
11319 ProcessRecord proc = conn.provider.proc;
11320 if (proc == null || proc.thread == null) {
11321 // Seems like the process is already cleaned up.
11325 // As far as we're concerned, this is just like receiving a
11326 // death notification... just a bit prematurely.
11327 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11328 + ") early provider death");
11329 final long ident = Binder.clearCallingIdentity();
11331 appDiedLocked(proc);
11333 Binder.restoreCallingIdentity(ident);
11339 public void appNotRespondingViaProvider(IBinder connection) {
11340 enforceCallingPermission(
11341 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11343 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11344 if (conn == null) {
11345 Slog.w(TAG, "ContentProviderConnection is null");
11349 final ProcessRecord host = conn.provider.proc;
11350 if (host == null) {
11351 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11355 mHandler.post(new Runnable() {
11357 public void run() {
11358 mAppErrors.appNotResponding(host, null, null, false,
11359 "ContentProvider not responding");
11364 public final void installSystemProviders() {
11365 List<ProviderInfo> providers;
11366 synchronized (this) {
11367 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11368 providers = generateApplicationProvidersLocked(app);
11369 if (providers != null) {
11370 for (int i=providers.size()-1; i>=0; i--) {
11371 ProviderInfo pi = (ProviderInfo)providers.get(i);
11372 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11373 Slog.w(TAG, "Not installing system proc provider " + pi.name
11374 + ": not system .apk");
11375 providers.remove(i);
11380 if (providers != null) {
11381 mSystemThread.installSystemProviders(providers);
11384 mCoreSettingsObserver = new CoreSettingsObserver(this);
11385 mFontScaleSettingObserver = new FontScaleSettingObserver();
11387 //mUsageStatsService.monitorPackages();
11390 private void startPersistentApps(int matchFlags) {
11391 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11393 synchronized (this) {
11395 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11396 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11397 for (ApplicationInfo app : apps) {
11398 if (!"android".equals(app.packageName)) {
11399 addAppLocked(app, false, null /* ABI override */);
11402 } catch (RemoteException ex) {
11408 * When a user is unlocked, we need to install encryption-unaware providers
11409 * belonging to any running apps.
11411 private void installEncryptionUnawareProviders(int userId) {
11412 // We're only interested in providers that are encryption unaware, and
11413 // we don't care about uninstalled apps, since there's no way they're
11414 // running at this point.
11415 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11417 synchronized (this) {
11418 final int NP = mProcessNames.getMap().size();
11419 for (int ip = 0; ip < NP; ip++) {
11420 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11421 final int NA = apps.size();
11422 for (int ia = 0; ia < NA; ia++) {
11423 final ProcessRecord app = apps.valueAt(ia);
11424 if (app.userId != userId || app.thread == null || app.unlocked) continue;
11426 final int NG = app.pkgList.size();
11427 for (int ig = 0; ig < NG; ig++) {
11429 final String pkgName = app.pkgList.keyAt(ig);
11430 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11431 .getPackageInfo(pkgName, matchFlags, userId);
11432 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11433 for (ProviderInfo pi : pkgInfo.providers) {
11434 // TODO: keep in sync with generateApplicationProvidersLocked
11435 final boolean processMatch = Objects.equals(pi.processName,
11436 app.processName) || pi.multiprocess;
11437 final boolean userMatch = isSingleton(pi.processName,
11438 pi.applicationInfo, pi.name, pi.flags)
11439 ? (app.userId == UserHandle.USER_SYSTEM) : true;
11440 if (processMatch && userMatch) {
11441 Log.v(TAG, "Installing " + pi);
11442 app.thread.scheduleInstallProvider(pi);
11444 Log.v(TAG, "Skipping " + pi);
11448 } catch (RemoteException ignored) {
11457 * Allows apps to retrieve the MIME type of a URI.
11458 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11459 * users, then it does not need permission to access the ContentProvider.
11460 * Either, it needs cross-user uri grants.
11462 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11464 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11465 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11467 public String getProviderMimeType(Uri uri, int userId) {
11468 enforceNotIsolatedCaller("getProviderMimeType");
11469 final String name = uri.getAuthority();
11470 int callingUid = Binder.getCallingUid();
11471 int callingPid = Binder.getCallingPid();
11473 boolean clearedIdentity = false;
11474 synchronized (this) {
11475 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11477 if (canClearIdentity(callingPid, callingUid, userId)) {
11478 clearedIdentity = true;
11479 ident = Binder.clearCallingIdentity();
11481 ContentProviderHolder holder = null;
11483 holder = getContentProviderExternalUnchecked(name, null, userId);
11484 if (holder != null) {
11485 return holder.provider.getType(uri);
11487 } catch (RemoteException e) {
11488 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11490 } catch (Exception e) {
11491 Log.w(TAG, "Exception while determining type of " + uri, e);
11494 // We need to clear the identity to call removeContentProviderExternalUnchecked
11495 if (!clearedIdentity) {
11496 ident = Binder.clearCallingIdentity();
11499 if (holder != null) {
11500 removeContentProviderExternalUnchecked(name, null, userId);
11503 Binder.restoreCallingIdentity(ident);
11510 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11511 if (UserHandle.getUserId(callingUid) == userId) {
11514 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11515 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11516 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11517 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11523 // =========================================================
11524 // GLOBAL MANAGEMENT
11525 // =========================================================
11527 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11528 boolean isolated, int isolatedUid) {
11529 String proc = customProcess != null ? customProcess : info.processName;
11530 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11531 final int userId = UserHandle.getUserId(info.uid);
11532 int uid = info.uid;
11534 if (isolatedUid == 0) {
11535 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11537 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11538 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11539 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11541 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11542 mNextIsolatedProcessUid++;
11543 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11544 // No process for this uid, use it.
11548 if (stepsLeft <= 0) {
11553 // Special case for startIsolatedProcess (internal only), where
11554 // the uid of the isolated process is specified by the caller.
11558 // Register the isolated UID with this application so BatteryStats knows to
11559 // attribute resource usage to the application.
11561 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11562 // about the process state of the isolated UID *before* it is registered with the
11563 // owning application.
11564 mBatteryStatsService.addIsolatedUid(uid, info.uid);
11566 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11567 if (!mBooted && !mBooting
11568 && userId == UserHandle.USER_SYSTEM
11569 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11570 r.persistent = true;
11572 addProcessNameLocked(r);
11576 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11577 String abiOverride) {
11580 app = getProcessRecordLocked(info.processName, info.uid, true);
11586 app = newProcessRecordLocked(info, null, isolated, 0);
11587 updateLruProcessLocked(app, false, null);
11588 updateOomAdjLocked();
11591 // This package really, really can not be stopped.
11593 AppGlobals.getPackageManager().setPackageStoppedState(
11594 info.packageName, false, UserHandle.getUserId(app.uid));
11595 } catch (RemoteException e) {
11596 } catch (IllegalArgumentException e) {
11597 Slog.w(TAG, "Failed trying to unstop package "
11598 + info.packageName + ": " + e);
11601 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11602 app.persistent = true;
11603 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11605 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11606 mPersistentStartingProcesses.add(app);
11607 startProcessLocked(app, "added application", app.processName, abiOverride,
11608 null /* entryPoint */, null /* entryPointArgs */);
11614 public void unhandledBack() {
11615 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11616 "unhandledBack()");
11618 synchronized(this) {
11619 final long origId = Binder.clearCallingIdentity();
11621 getFocusedStack().unhandledBackLocked();
11623 Binder.restoreCallingIdentity(origId);
11628 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11629 enforceNotIsolatedCaller("openContentUri");
11630 final int userId = UserHandle.getCallingUserId();
11631 String name = uri.getAuthority();
11632 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11633 ParcelFileDescriptor pfd = null;
11635 // We record the binder invoker's uid in thread-local storage before
11636 // going to the content provider to open the file. Later, in the code
11637 // that handles all permissions checks, we look for this uid and use
11638 // that rather than the Activity Manager's own uid. The effect is that
11639 // we do the check against the caller's permissions even though it looks
11640 // to the content provider like the Activity Manager itself is making
11642 Binder token = new Binder();
11643 sCallerIdentity.set(new Identity(
11644 token, Binder.getCallingPid(), Binder.getCallingUid()));
11646 pfd = cph.provider.openFile(null, uri, "r", null, token);
11647 } catch (FileNotFoundException e) {
11648 // do nothing; pfd will be returned null
11650 // Ensure that whatever happens, we clean up the identity state
11651 sCallerIdentity.remove();
11652 // Ensure we're done with the provider.
11653 removeContentProviderExternalUnchecked(name, null, userId);
11656 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11661 // Actually is sleeping or shutting down or whatever else in the future
11662 // is an inactive state.
11663 boolean isSleepingOrShuttingDownLocked() {
11664 return isSleepingLocked() || mShuttingDown;
11667 boolean isShuttingDownLocked() {
11668 return mShuttingDown;
11671 boolean isSleepingLocked() {
11675 void onWakefulnessChanged(int wakefulness) {
11676 synchronized(this) {
11677 mWakefulness = wakefulness;
11678 updateSleepIfNeededLocked();
11682 void finishRunningVoiceLocked() {
11683 if (mRunningVoice != null) {
11684 mRunningVoice = null;
11685 mVoiceWakeLock.release();
11686 updateSleepIfNeededLocked();
11690 void startTimeTrackingFocusedActivityLocked() {
11691 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11692 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11696 void updateSleepIfNeededLocked() {
11697 if (mSleeping && !shouldSleepLocked()) {
11699 startTimeTrackingFocusedActivityLocked();
11700 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11701 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11702 updateOomAdjLocked();
11703 } else if (!mSleeping && shouldSleepLocked()) {
11705 if (mCurAppTimeTracker != null) {
11706 mCurAppTimeTracker.stop();
11708 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11709 mStackSupervisor.goingToSleepLocked();
11710 updateOomAdjLocked();
11712 // Initialize the wake times of all processes.
11713 checkExcessivePowerUsageLocked(false);
11714 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11715 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11716 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11720 private boolean shouldSleepLocked() {
11721 // Resume applications while running a voice interactor.
11722 if (mRunningVoice != null) {
11726 // TODO: Transform the lock screen state into a sleep token instead.
11727 switch (mWakefulness) {
11728 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11729 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11730 case PowerManagerInternal.WAKEFULNESS_DOZING:
11731 // Pause applications whenever the lock screen is shown or any sleep
11732 // tokens have been acquired.
11733 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11734 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11736 // If we're asleep then pause applications unconditionally.
11741 /** Pokes the task persister. */
11742 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11743 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11746 /** Notifies all listeners when the task stack has changed. */
11747 void notifyTaskStackChangedLocked() {
11748 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11749 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11750 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11751 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11754 /** Notifies all listeners when an Activity is pinned. */
11755 void notifyActivityPinnedLocked() {
11756 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11757 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11761 * Notifies all listeners when an attempt was made to start an an activity that is already
11762 * running in the pinned stack and the activity was not actually started, but the task is
11763 * either brought to the front or a new Intent is delivered to it.
11765 void notifyPinnedActivityRestartAttemptLocked() {
11766 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11767 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11770 /** Notifies all listeners when the pinned stack animation ends. */
11772 public void notifyPinnedStackAnimationEnded() {
11773 synchronized (this) {
11774 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11775 mHandler.obtainMessage(
11776 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11781 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11782 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11786 public boolean shutdown(int timeout) {
11787 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11788 != PackageManager.PERMISSION_GRANTED) {
11789 throw new SecurityException("Requires permission "
11790 + android.Manifest.permission.SHUTDOWN);
11793 boolean timedout = false;
11795 synchronized(this) {
11796 mShuttingDown = true;
11797 updateEventDispatchingLocked();
11798 timedout = mStackSupervisor.shutdownLocked(timeout);
11801 mAppOpsService.shutdown();
11802 if (mUsageStatsService != null) {
11803 mUsageStatsService.prepareShutdown();
11805 mBatteryStatsService.shutdown();
11806 synchronized (this) {
11807 mProcessStats.shutdownLocked();
11808 notifyTaskPersisterLocked(null, true);
11814 public final void activitySlept(IBinder token) {
11815 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11817 final long origId = Binder.clearCallingIdentity();
11819 synchronized (this) {
11820 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11822 mStackSupervisor.activitySleptLocked(r);
11826 Binder.restoreCallingIdentity(origId);
11829 private String lockScreenShownToString() {
11830 switch (mLockScreenShown) {
11831 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11832 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11833 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11834 default: return "Unknown=" + mLockScreenShown;
11838 void logLockScreen(String msg) {
11839 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11840 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11841 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11842 + " mSleeping=" + mSleeping);
11845 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11846 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11847 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11848 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11849 boolean wasRunningVoice = mRunningVoice != null;
11850 mRunningVoice = session;
11851 if (!wasRunningVoice) {
11852 mVoiceWakeLock.acquire();
11853 updateSleepIfNeededLocked();
11858 private void updateEventDispatchingLocked() {
11859 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11862 public void setLockScreenShown(boolean showing, boolean occluded) {
11863 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11864 != PackageManager.PERMISSION_GRANTED) {
11865 throw new SecurityException("Requires permission "
11866 + android.Manifest.permission.DEVICE_POWER);
11869 synchronized(this) {
11870 long ident = Binder.clearCallingIdentity();
11872 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11873 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11874 if (showing && occluded) {
11875 // The lock screen is currently showing, but is occluded by a window that can
11876 // show on top of the lock screen. In this can we want to dismiss the docked
11877 // stack since it will be complicated/risky to try to put the activity on top
11878 // of the lock screen in the right fullscreen configuration.
11879 mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11880 mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11883 updateSleepIfNeededLocked();
11885 Binder.restoreCallingIdentity(ident);
11891 public void notifyLockedProfile(@UserIdInt int userId) {
11893 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11894 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11896 } catch (RemoteException ex) {
11897 throw new SecurityException("Fail to check is caller a privileged app", ex);
11900 synchronized (this) {
11901 if (mStackSupervisor.isUserLockedProfile(userId)) {
11902 final long ident = Binder.clearCallingIdentity();
11904 final int currentUserId = mUserController.getCurrentUserIdLocked();
11906 // Drop locked freeform tasks out into the fullscreen stack.
11907 // TODO: Redact the tasks in place. It's much better to keep them on the screen
11908 // where they were before, but in an obscured state.
11909 mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11911 if (mUserController.isLockScreenDisabled(currentUserId)) {
11912 // If there is no device lock, we will show the profile's credential page.
11913 mActivityStarter.showConfirmDeviceCredential(userId);
11915 // Showing launcher to avoid user entering credential twice.
11916 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11919 Binder.restoreCallingIdentity(ident);
11926 public void startConfirmDeviceCredentialIntent(Intent intent) {
11927 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11928 synchronized (this) {
11929 final long ident = Binder.clearCallingIdentity();
11931 mActivityStarter.startConfirmCredentialIntent(intent);
11933 Binder.restoreCallingIdentity(ident);
11939 public void stopAppSwitches() {
11940 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11941 != PackageManager.PERMISSION_GRANTED) {
11942 throw new SecurityException("viewquires permission "
11943 + android.Manifest.permission.STOP_APP_SWITCHES);
11946 synchronized(this) {
11947 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11948 + APP_SWITCH_DELAY_TIME;
11949 mDidAppSwitch = false;
11950 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11951 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11952 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11956 public void resumeAppSwitches() {
11957 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11958 != PackageManager.PERMISSION_GRANTED) {
11959 throw new SecurityException("Requires permission "
11960 + android.Manifest.permission.STOP_APP_SWITCHES);
11963 synchronized(this) {
11964 // Note that we don't execute any pending app switches... we will
11965 // let those wait until either the timeout, or the next start
11966 // activity request.
11967 mAppSwitchesAllowedTime = 0;
11971 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11972 int callingPid, int callingUid, String name) {
11973 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11977 int perm = checkComponentPermission(
11978 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11979 sourceUid, -1, true);
11980 if (perm == PackageManager.PERMISSION_GRANTED) {
11984 // If the actual IPC caller is different from the logical source, then
11985 // also see if they are allowed to control app switches.
11986 if (callingUid != -1 && callingUid != sourceUid) {
11987 perm = checkComponentPermission(
11988 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11989 callingUid, -1, true);
11990 if (perm == PackageManager.PERMISSION_GRANTED) {
11995 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11999 public void setDebugApp(String packageName, boolean waitForDebugger,
12000 boolean persistent) {
12001 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12004 long ident = Binder.clearCallingIdentity();
12006 // Note that this is not really thread safe if there are multiple
12007 // callers into it at the same time, but that's not a situation we
12010 final ContentResolver resolver = mContext.getContentResolver();
12011 Settings.Global.putString(
12012 resolver, Settings.Global.DEBUG_APP,
12014 Settings.Global.putInt(
12015 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12016 waitForDebugger ? 1 : 0);
12019 synchronized (this) {
12021 mOrigDebugApp = mDebugApp;
12022 mOrigWaitForDebugger = mWaitForDebugger;
12024 mDebugApp = packageName;
12025 mWaitForDebugger = waitForDebugger;
12026 mDebugTransient = !persistent;
12027 if (packageName != null) {
12028 forceStopPackageLocked(packageName, -1, false, false, true, true,
12029 false, UserHandle.USER_ALL, "set debug app");
12033 Binder.restoreCallingIdentity(ident);
12037 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12038 synchronized (this) {
12039 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12040 if (!isDebuggable) {
12041 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12042 throw new SecurityException("Process not debuggable: " + app.packageName);
12046 mTrackAllocationApp = processName;
12050 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12051 synchronized (this) {
12052 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12053 if (!isDebuggable) {
12054 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12055 throw new SecurityException("Process not debuggable: " + app.packageName);
12058 mProfileApp = processName;
12059 mProfileFile = profilerInfo.profileFile;
12060 if (mProfileFd != null) {
12062 mProfileFd.close();
12063 } catch (IOException e) {
12067 mProfileFd = profilerInfo.profileFd;
12068 mSamplingInterval = profilerInfo.samplingInterval;
12069 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12074 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12075 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12076 if (!isDebuggable) {
12077 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12078 throw new SecurityException("Process not debuggable: " + app.packageName);
12081 mNativeDebuggingApp = processName;
12085 public void setAlwaysFinish(boolean enabled) {
12086 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12087 "setAlwaysFinish()");
12089 long ident = Binder.clearCallingIdentity();
12091 Settings.Global.putInt(
12092 mContext.getContentResolver(),
12093 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12095 synchronized (this) {
12096 mAlwaysFinishActivities = enabled;
12099 Binder.restoreCallingIdentity(ident);
12104 public void setLenientBackgroundCheck(boolean enabled) {
12105 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12106 "setLenientBackgroundCheck()");
12108 long ident = Binder.clearCallingIdentity();
12110 Settings.Global.putInt(
12111 mContext.getContentResolver(),
12112 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12114 synchronized (this) {
12115 mLenientBackgroundCheck = enabled;
12118 Binder.restoreCallingIdentity(ident);
12123 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12124 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12125 "setActivityController()");
12126 synchronized (this) {
12127 mController = controller;
12128 mControllerIsAMonkey = imAMonkey;
12129 Watchdog.getInstance().setActivityController(controller);
12134 public void setUserIsMonkey(boolean userIsMonkey) {
12135 synchronized (this) {
12136 synchronized (mPidsSelfLocked) {
12137 final int callingPid = Binder.getCallingPid();
12138 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12139 if (precessRecord == null) {
12140 throw new SecurityException("Unknown process: " + callingPid);
12142 if (precessRecord.instrumentationUiAutomationConnection == null) {
12143 throw new SecurityException("Only an instrumentation process "
12144 + "with a UiAutomation can call setUserIsMonkey");
12147 mUserIsMonkey = userIsMonkey;
12152 public boolean isUserAMonkey() {
12153 synchronized (this) {
12154 // If there is a controller also implies the user is a monkey.
12155 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12159 public void requestBugReport(int bugreportType) {
12160 String service = null;
12161 switch (bugreportType) {
12162 case ActivityManager.BUGREPORT_OPTION_FULL:
12163 service = "bugreport";
12165 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12166 service = "bugreportplus";
12168 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12169 service = "bugreportremote";
12171 case ActivityManager.BUGREPORT_OPTION_WEAR:
12172 service = "bugreportwear";
12175 if (service == null) {
12176 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12179 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12180 SystemProperties.set("ctl.start", service);
12183 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12184 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12187 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12188 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12189 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12191 return KEY_DISPATCHING_TIMEOUT;
12195 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12196 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12197 != PackageManager.PERMISSION_GRANTED) {
12198 throw new SecurityException("Requires permission "
12199 + android.Manifest.permission.FILTER_EVENTS);
12201 ProcessRecord proc;
12203 synchronized (this) {
12204 synchronized (mPidsSelfLocked) {
12205 proc = mPidsSelfLocked.get(pid);
12207 timeout = getInputDispatchingTimeoutLocked(proc);
12210 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12218 * Handle input dispatching timeouts.
12219 * Returns whether input dispatching should be aborted or not.
12221 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12222 final ActivityRecord activity, final ActivityRecord parent,
12223 final boolean aboveSystem, String reason) {
12224 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12225 != PackageManager.PERMISSION_GRANTED) {
12226 throw new SecurityException("Requires permission "
12227 + android.Manifest.permission.FILTER_EVENTS);
12230 final String annotation;
12231 if (reason == null) {
12232 annotation = "Input dispatching timed out";
12234 annotation = "Input dispatching timed out (" + reason + ")";
12237 if (proc != null) {
12238 synchronized (this) {
12239 if (proc.debugging) {
12244 // Give more time since we were dexopting.
12245 mDidDexOpt = false;
12249 if (proc.instrumentationClass != null) {
12250 Bundle info = new Bundle();
12251 info.putString("shortMsg", "keyDispatchingTimedOut");
12252 info.putString("longMsg", annotation);
12253 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12257 mHandler.post(new Runnable() {
12259 public void run() {
12260 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12269 public Bundle getAssistContextExtras(int requestType) {
12270 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12271 null, null, true /* focused */, true /* newSessionId */,
12272 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12276 synchronized (pae) {
12277 while (!pae.haveResult) {
12280 } catch (InterruptedException e) {
12284 synchronized (this) {
12285 buildAssistBundleLocked(pae, pae.result);
12286 mPendingAssistExtras.remove(pae);
12287 mUiHandler.removeCallbacks(pae);
12293 public boolean isAssistDataAllowedOnCurrentActivity() {
12295 synchronized (this) {
12296 userId = mUserController.getCurrentUserIdLocked();
12297 ActivityRecord activity = getFocusedStack().topActivity();
12298 if (activity == null) {
12301 userId = activity.userId;
12303 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12304 Context.DEVICE_POLICY_SERVICE);
12305 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12309 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12310 long ident = Binder.clearCallingIdentity();
12312 synchronized (this) {
12313 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12314 ActivityRecord top = getFocusedStack().topActivity();
12315 if (top != caller) {
12316 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12317 + " is not current top " + top);
12320 if (!top.nowVisible) {
12321 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12322 + " is not visible");
12326 AssistUtils utils = new AssistUtils(mContext);
12327 return utils.showSessionForActiveService(args,
12328 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12330 Binder.restoreCallingIdentity(ident);
12335 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12336 Bundle receiverExtras,
12337 IBinder activityToken, boolean focused, boolean newSessionId) {
12338 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12339 activityToken, focused, newSessionId,
12340 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12344 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12345 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12346 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12347 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12348 "enqueueAssistContext()");
12349 synchronized (this) {
12350 ActivityRecord activity = getFocusedStack().topActivity();
12351 if (activity == null) {
12352 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12355 if (activity.app == null || activity.app.thread == null) {
12356 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12360 if (activityToken != null) {
12361 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12362 if (activity != caller) {
12363 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12364 + " is not current top " + activity);
12369 activity = ActivityRecord.forTokenLocked(activityToken);
12370 if (activity == null) {
12371 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12372 + " couldn't be found");
12377 PendingAssistExtras pae;
12378 Bundle extras = new Bundle();
12379 if (args != null) {
12380 extras.putAll(args);
12382 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12383 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12384 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12386 // Increment the sessionId if necessary
12387 if (newSessionId) {
12391 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12392 requestType, mViSessionId);
12393 mPendingAssistExtras.add(pae);
12394 mUiHandler.postDelayed(pae, timeout);
12395 } catch (RemoteException e) {
12396 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12403 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12404 IResultReceiver receiver;
12405 synchronized (this) {
12406 mPendingAssistExtras.remove(pae);
12407 receiver = pae.receiver;
12409 if (receiver != null) {
12410 // Caller wants result sent back to them.
12411 Bundle sendBundle = new Bundle();
12412 // At least return the receiver extras
12413 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12414 pae.receiverExtras);
12416 pae.receiver.send(0, sendBundle);
12417 } catch (RemoteException e) {
12422 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12423 if (result != null) {
12424 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12426 if (pae.hint != null) {
12427 pae.extras.putBoolean(pae.hint, true);
12431 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12432 AssistContent content, Uri referrer) {
12433 PendingAssistExtras pae = (PendingAssistExtras)token;
12434 synchronized (pae) {
12435 pae.result = extras;
12436 pae.structure = structure;
12437 pae.content = content;
12438 if (referrer != null) {
12439 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12441 pae.haveResult = true;
12443 if (pae.intent == null && pae.receiver == null) {
12444 // Caller is just waiting for the result.
12449 // We are now ready to launch the assist activity.
12450 IResultReceiver sendReceiver = null;
12451 Bundle sendBundle = null;
12452 synchronized (this) {
12453 buildAssistBundleLocked(pae, extras);
12454 boolean exists = mPendingAssistExtras.remove(pae);
12455 mUiHandler.removeCallbacks(pae);
12460 if ((sendReceiver=pae.receiver) != null) {
12461 // Caller wants result sent back to them.
12462 sendBundle = new Bundle();
12463 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12464 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12465 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12466 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12467 pae.receiverExtras);
12470 if (sendReceiver != null) {
12472 sendReceiver.send(0, sendBundle);
12473 } catch (RemoteException e) {
12478 long ident = Binder.clearCallingIdentity();
12480 pae.intent.replaceExtras(pae.extras);
12481 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12482 | Intent.FLAG_ACTIVITY_SINGLE_TOP
12483 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12484 closeSystemDialogs("assist");
12486 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12487 } catch (ActivityNotFoundException e) {
12488 Slog.w(TAG, "No activity to handle assist action.", e);
12491 Binder.restoreCallingIdentity(ident);
12495 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12497 return enqueueAssistContext(requestType, intent, hint, null, null, null,
12498 true /* focused */, true /* newSessionId */,
12499 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12502 public void registerProcessObserver(IProcessObserver observer) {
12503 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12504 "registerProcessObserver()");
12505 synchronized (this) {
12506 mProcessObservers.register(observer);
12511 public void unregisterProcessObserver(IProcessObserver observer) {
12512 synchronized (this) {
12513 mProcessObservers.unregister(observer);
12518 public void registerUidObserver(IUidObserver observer, int which) {
12519 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12520 "registerUidObserver()");
12521 synchronized (this) {
12522 mUidObservers.register(observer, which);
12527 public void unregisterUidObserver(IUidObserver observer) {
12528 synchronized (this) {
12529 mUidObservers.unregister(observer);
12534 public boolean convertFromTranslucent(IBinder token) {
12535 final long origId = Binder.clearCallingIdentity();
12537 synchronized (this) {
12538 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12542 final boolean translucentChanged = r.changeWindowTranslucency(true);
12543 if (translucentChanged) {
12544 r.task.stack.releaseBackgroundResources(r);
12545 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12547 mWindowManager.setAppFullscreen(token, true);
12548 return translucentChanged;
12551 Binder.restoreCallingIdentity(origId);
12556 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12557 final long origId = Binder.clearCallingIdentity();
12559 synchronized (this) {
12560 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12564 int index = r.task.mActivities.lastIndexOf(r);
12566 ActivityRecord under = r.task.mActivities.get(index - 1);
12567 under.returningOptions = options;
12569 final boolean translucentChanged = r.changeWindowTranslucency(false);
12570 if (translucentChanged) {
12571 r.task.stack.convertActivityToTranslucent(r);
12573 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12574 mWindowManager.setAppFullscreen(token, false);
12575 return translucentChanged;
12578 Binder.restoreCallingIdentity(origId);
12583 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12584 final long origId = Binder.clearCallingIdentity();
12586 synchronized (this) {
12587 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12589 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12594 Binder.restoreCallingIdentity(origId);
12599 public boolean isBackgroundVisibleBehind(IBinder token) {
12600 final long origId = Binder.clearCallingIdentity();
12602 synchronized (this) {
12603 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12604 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12605 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12606 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12610 Binder.restoreCallingIdentity(origId);
12615 public ActivityOptions getActivityOptions(IBinder token) {
12616 final long origId = Binder.clearCallingIdentity();
12618 synchronized (this) {
12619 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12621 final ActivityOptions activityOptions = r.pendingOptions;
12622 r.pendingOptions = null;
12623 return activityOptions;
12628 Binder.restoreCallingIdentity(origId);
12633 public void setImmersive(IBinder token, boolean immersive) {
12634 synchronized(this) {
12635 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12637 throw new IllegalArgumentException();
12639 r.immersive = immersive;
12641 // update associated state if we're frontmost
12642 if (r == mFocusedActivity) {
12643 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12644 applyUpdateLockStateLocked(r);
12650 public boolean isImmersive(IBinder token) {
12651 synchronized (this) {
12652 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12654 throw new IllegalArgumentException();
12656 return r.immersive;
12660 public void setVrThread(int tid) {
12661 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12662 throw new UnsupportedOperationException("VR mode not supported on this device!");
12665 synchronized (this) {
12666 ProcessRecord proc;
12667 synchronized (mPidsSelfLocked) {
12668 final int pid = Binder.getCallingPid();
12669 proc = mPidsSelfLocked.get(pid);
12671 if (proc != null && mInVrMode && tid >= 0) {
12672 // ensure the tid belongs to the process
12673 if (!Process.isThreadInProcess(pid, tid)) {
12674 throw new IllegalArgumentException("VR thread does not belong to process");
12677 // reset existing VR thread to CFS if this thread still exists and belongs to
12678 // the calling process
12679 if (proc.vrThreadTid != 0
12680 && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12682 Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12683 } catch (IllegalArgumentException e) {
12684 // Ignore this. Only occurs in race condition where previous VR thread
12685 // was destroyed during this method call.
12689 proc.vrThreadTid = tid;
12691 // promote to FIFO now if the tid is non-zero
12693 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12694 proc.vrThreadTid > 0) {
12695 Process.setThreadScheduler(proc.vrThreadTid,
12696 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12698 } catch (IllegalArgumentException e) {
12699 Slog.e(TAG, "Failed to set scheduling policy, thread does"
12700 + " not exist:\n" + e);
12708 public void setRenderThread(int tid) {
12709 synchronized (this) {
12710 ProcessRecord proc;
12711 synchronized (mPidsSelfLocked) {
12712 int pid = Binder.getCallingPid();
12713 proc = mPidsSelfLocked.get(pid);
12714 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12715 // ensure the tid belongs to the process
12716 if (!Process.isThreadInProcess(pid, tid)) {
12717 throw new IllegalArgumentException(
12718 "Render thread does not belong to process");
12720 proc.renderThreadTid = tid;
12721 if (DEBUG_OOM_ADJ) {
12722 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12724 // promote to FIFO now
12725 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12726 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12727 if (mUseFifoUiScheduling) {
12728 Process.setThreadScheduler(proc.renderThreadTid,
12729 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12731 Process.setThreadPriority(proc.renderThreadTid, -10);
12735 if (DEBUG_OOM_ADJ) {
12736 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12737 "PID: " + pid + ", TID: " + tid + " FIFO: " +
12738 mUseFifoUiScheduling);
12746 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12747 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12748 throw new UnsupportedOperationException("VR mode not supported on this device!");
12751 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12754 synchronized (this) {
12755 r = ActivityRecord.isInStackLocked(token);
12759 throw new IllegalArgumentException();
12763 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12764 VrManagerInternal.NO_ERROR) {
12768 synchronized(this) {
12769 r.requestedVrComponent = (enabled) ? packageName : null;
12771 // Update associated state if this activity is currently focused
12772 if (r == mFocusedActivity) {
12773 applyUpdateVrModeLocked(r);
12780 public boolean isVrModePackageEnabled(ComponentName packageName) {
12781 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12782 throw new UnsupportedOperationException("VR mode not supported on this device!");
12785 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12787 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12788 VrManagerInternal.NO_ERROR;
12791 public boolean isTopActivityImmersive() {
12792 enforceNotIsolatedCaller("startActivity");
12793 synchronized (this) {
12794 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12795 return (r != null) ? r.immersive : false;
12800 public boolean isTopOfTask(IBinder token) {
12801 synchronized (this) {
12802 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12804 throw new IllegalArgumentException();
12806 return r.task.getTopActivity() == r;
12811 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12812 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12813 String msg = "Permission Denial: setHasTopUi() from pid="
12814 + Binder.getCallingPid()
12815 + ", uid=" + Binder.getCallingUid()
12816 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12818 throw new SecurityException(msg);
12820 final int pid = Binder.getCallingPid();
12821 final long origId = Binder.clearCallingIdentity();
12823 synchronized (this) {
12824 boolean changed = false;
12826 synchronized (mPidsSelfLocked) {
12827 pr = mPidsSelfLocked.get(pid);
12829 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12832 if (pr.hasTopUi != hasTopUi) {
12833 Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12834 pr.hasTopUi = hasTopUi;
12839 updateOomAdjLocked(pr);
12843 Binder.restoreCallingIdentity(origId);
12847 public final void enterSafeMode() {
12848 synchronized(this) {
12849 // It only makes sense to do this before the system is ready
12850 // and started launching other packages.
12851 if (!mSystemReady) {
12853 AppGlobals.getPackageManager().enterSafeMode();
12854 } catch (RemoteException e) {
12862 public final void showSafeModeOverlay() {
12863 View v = LayoutInflater.from(mContext).inflate(
12864 com.android.internal.R.layout.safe_mode, null);
12865 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12866 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12867 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12868 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12869 lp.gravity = Gravity.BOTTOM | Gravity.START;
12870 lp.format = v.getBackground().getOpacity();
12871 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12872 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12873 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12874 ((WindowManager)mContext.getSystemService(
12875 Context.WINDOW_SERVICE)).addView(v, lp);
12878 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12879 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12882 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12883 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12884 synchronized (stats) {
12885 if (mBatteryStatsService.isOnBattery()) {
12886 mBatteryStatsService.enforceCallingPermission();
12887 int MY_UID = Binder.getCallingUid();
12889 if (sender == null) {
12892 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12894 BatteryStatsImpl.Uid.Pkg pkg =
12895 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12896 sourcePkg != null ? sourcePkg : rec.key.packageName);
12897 pkg.noteWakeupAlarmLocked(tag);
12902 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12903 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12906 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12907 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12908 synchronized (stats) {
12909 mBatteryStatsService.enforceCallingPermission();
12910 int MY_UID = Binder.getCallingUid();
12912 if (sender == null) {
12915 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12917 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12921 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12922 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12925 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12926 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12927 synchronized (stats) {
12928 mBatteryStatsService.enforceCallingPermission();
12929 int MY_UID = Binder.getCallingUid();
12931 if (sender == null) {
12934 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12936 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12940 public boolean killPids(int[] pids, String pReason, boolean secure) {
12941 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12942 throw new SecurityException("killPids only available to the system");
12944 String reason = (pReason == null) ? "Unknown" : pReason;
12945 // XXX Note: don't acquire main activity lock here, because the window
12946 // manager calls in with its locks held.
12948 boolean killed = false;
12949 synchronized (mPidsSelfLocked) {
12951 for (int i=0; i<pids.length; i++) {
12952 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12953 if (proc != null) {
12954 int type = proc.setAdj;
12955 if (type > worstType) {
12961 // If the worst oom_adj is somewhere in the cached proc LRU range,
12962 // then constrain it so we will kill all cached procs.
12963 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12964 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12965 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12968 // If this is not a secure call, don't let it kill processes that
12970 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12971 worstType = ProcessList.SERVICE_ADJ;
12974 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12975 for (int i=0; i<pids.length; i++) {
12976 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12977 if (proc == null) {
12980 int adj = proc.setAdj;
12981 if (adj >= worstType && !proc.killedByAm) {
12982 proc.kill(reason, true);
12991 public void killUid(int appId, int userId, String reason) {
12992 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12993 synchronized (this) {
12994 final long identity = Binder.clearCallingIdentity();
12996 killPackageProcessesLocked(null, appId, userId,
12997 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12998 reason != null ? reason : "kill uid");
13000 Binder.restoreCallingIdentity(identity);
13006 public boolean killProcessesBelowForeground(String reason) {
13007 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13008 throw new SecurityException("killProcessesBelowForeground() only available to system");
13011 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13014 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13015 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13016 throw new SecurityException("killProcessesBelowAdj() only available to system");
13019 boolean killed = false;
13020 synchronized (mPidsSelfLocked) {
13021 final int size = mPidsSelfLocked.size();
13022 for (int i = 0; i < size; i++) {
13023 final int pid = mPidsSelfLocked.keyAt(i);
13024 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13025 if (proc == null) continue;
13027 final int adj = proc.setAdj;
13028 if (adj > belowAdj && !proc.killedByAm) {
13029 proc.kill(reason, true);
13038 public void hang(final IBinder who, boolean allowRestart) {
13039 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13040 != PackageManager.PERMISSION_GRANTED) {
13041 throw new SecurityException("Requires permission "
13042 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13045 final IBinder.DeathRecipient death = new DeathRecipient() {
13047 public void binderDied() {
13048 synchronized (this) {
13055 who.linkToDeath(death, 0);
13056 } catch (RemoteException e) {
13057 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13061 synchronized (this) {
13062 Watchdog.getInstance().setAllowRestart(allowRestart);
13063 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13064 synchronized (death) {
13065 while (who.isBinderAlive()) {
13068 } catch (InterruptedException e) {
13072 Watchdog.getInstance().setAllowRestart(true);
13077 public void restart() {
13078 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13079 != PackageManager.PERMISSION_GRANTED) {
13080 throw new SecurityException("Requires permission "
13081 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13084 Log.i(TAG, "Sending shutdown broadcast...");
13086 BroadcastReceiver br = new BroadcastReceiver() {
13087 @Override public void onReceive(Context context, Intent intent) {
13088 // Now the broadcast is done, finish up the low-level shutdown.
13089 Log.i(TAG, "Shutting down activity manager...");
13091 Log.i(TAG, "Shutdown complete, restarting!");
13092 Process.killProcess(Process.myPid());
13097 // First send the high-level shut down broadcast.
13098 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13099 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13100 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13101 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13102 mContext.sendOrderedBroadcastAsUser(intent,
13103 UserHandle.ALL, null, br, mHandler, 0, null, null);
13105 br.onReceive(mContext, intent);
13108 private long getLowRamTimeSinceIdle(long now) {
13109 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13113 public void performIdleMaintenance() {
13114 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13115 != PackageManager.PERMISSION_GRANTED) {
13116 throw new SecurityException("Requires permission "
13117 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13120 synchronized (this) {
13121 final long now = SystemClock.uptimeMillis();
13122 final long timeSinceLastIdle = now - mLastIdleTime;
13123 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13124 mLastIdleTime = now;
13125 mLowRamTimeSinceLastIdle = 0;
13126 if (mLowRamStartTime != 0) {
13127 mLowRamStartTime = now;
13130 StringBuilder sb = new StringBuilder(128);
13131 sb.append("Idle maintenance over ");
13132 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13133 sb.append(" low RAM for ");
13134 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13135 Slog.i(TAG, sb.toString());
13137 // If at least 1/3 of our time since the last idle period has been spent
13138 // with RAM low, then we want to kill processes.
13139 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13141 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13142 ProcessRecord proc = mLruProcesses.get(i);
13143 if (proc.notCachedSinceIdle) {
13144 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13145 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13146 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13147 if (doKilling && proc.initialIdlePss != 0
13148 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13149 sb = new StringBuilder(128);
13151 sb.append(proc.processName);
13152 sb.append(" in idle maint: pss=");
13153 sb.append(proc.lastPss);
13154 sb.append(", swapPss=");
13155 sb.append(proc.lastSwapPss);
13156 sb.append(", initialPss=");
13157 sb.append(proc.initialIdlePss);
13158 sb.append(", period=");
13159 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13160 sb.append(", lowRamPeriod=");
13161 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13162 Slog.wtfQuiet(TAG, sb.toString());
13163 proc.kill("idle maint (pss " + proc.lastPss
13164 + " from " + proc.initialIdlePss + ")", true);
13167 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13168 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13169 proc.notCachedSinceIdle = true;
13170 proc.initialIdlePss = 0;
13171 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13172 mTestPssMode, isSleepingLocked(), now);
13176 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13177 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13182 public void sendIdleJobTrigger() {
13183 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13184 != PackageManager.PERMISSION_GRANTED) {
13185 throw new SecurityException("Requires permission "
13186 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13189 final long ident = Binder.clearCallingIdentity();
13191 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13192 .setPackage("android")
13193 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13194 broadcastIntent(null, intent, null, null, 0, null, null, null,
13195 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13197 Binder.restoreCallingIdentity(ident);
13201 private void retrieveSettings() {
13202 final ContentResolver resolver = mContext.getContentResolver();
13203 final boolean freeformWindowManagement =
13204 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13205 || Settings.Global.getInt(
13206 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13207 final boolean supportsPictureInPicture =
13208 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13210 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13211 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13212 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13213 final boolean alwaysFinishActivities =
13214 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13215 final boolean lenientBackgroundCheck =
13216 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13217 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13218 final boolean forceResizable = Settings.Global.getInt(
13219 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13220 final boolean supportsLeanbackOnly =
13221 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13223 // Transfer any global setting for forcing RTL layout, into a System Property
13224 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13226 final Configuration configuration = new Configuration();
13227 Settings.System.getConfiguration(resolver, configuration);
13229 // This will take care of setting the correct layout direction flags
13230 configuration.setLayoutDirection(configuration.locale);
13233 synchronized (this) {
13234 mDebugApp = mOrigDebugApp = debugApp;
13235 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13236 mAlwaysFinishActivities = alwaysFinishActivities;
13237 mLenientBackgroundCheck = lenientBackgroundCheck;
13238 mSupportsLeanbackOnly = supportsLeanbackOnly;
13239 mForceResizableActivities = forceResizable;
13240 mWindowManager.setForceResizableTasks(mForceResizableActivities);
13241 if (supportsMultiWindow || forceResizable) {
13242 mSupportsMultiWindow = true;
13243 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13244 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13246 mSupportsMultiWindow = false;
13247 mSupportsFreeformWindowManagement = false;
13248 mSupportsPictureInPicture = false;
13250 // This happens before any activities are started, so we can
13251 // change mConfiguration in-place.
13252 updateConfigurationLocked(configuration, null, true);
13253 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13254 "Initial config: " + mConfiguration);
13256 // Load resources only after the current configuration has been set.
13257 final Resources res = mContext.getResources();
13258 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13259 mThumbnailWidth = res.getDimensionPixelSize(
13260 com.android.internal.R.dimen.thumbnail_width);
13261 mThumbnailHeight = res.getDimensionPixelSize(
13262 com.android.internal.R.dimen.thumbnail_height);
13263 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13264 com.android.internal.R.string.config_defaultPictureInPictureBounds));
13265 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13266 com.android.internal.R.string.config_appsNotReportingCrashes));
13267 if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13268 mFullscreenThumbnailScale = (float) res
13269 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13270 (float) mConfiguration.screenWidthDp;
13272 mFullscreenThumbnailScale = res.getFraction(
13273 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13278 public boolean testIsSystemReady() {
13279 // no need to synchronize(this) just to read & return the value
13280 return mSystemReady;
13283 public void systemReady(final Runnable goingCallback) {
13284 synchronized(this) {
13285 if (mSystemReady) {
13286 // If we're done calling all the receivers, run the next "boot phase" passed in
13287 // by the SystemServer
13288 if (goingCallback != null) {
13289 goingCallback.run();
13294 mLocalDeviceIdleController
13295 = LocalServices.getService(DeviceIdleController.LocalService.class);
13297 // Make sure we have the current profile info, since it is needed for security checks.
13298 mUserController.onSystemReady();
13299 mRecentTasks.onSystemReadyLocked();
13300 mAppOpsService.systemReady();
13301 mSystemReady = true;
13304 ArrayList<ProcessRecord> procsToKill = null;
13305 synchronized(mPidsSelfLocked) {
13306 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13307 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13308 if (!isAllowedWhileBooting(proc.info)){
13309 if (procsToKill == null) {
13310 procsToKill = new ArrayList<ProcessRecord>();
13312 procsToKill.add(proc);
13317 synchronized(this) {
13318 if (procsToKill != null) {
13319 for (int i=procsToKill.size()-1; i>=0; i--) {
13320 ProcessRecord proc = procsToKill.get(i);
13321 Slog.i(TAG, "Removing system update proc: " + proc);
13322 removeProcessLocked(proc, true, false, "system update done");
13326 // Now that we have cleaned up any update processes, we
13327 // are ready to start launching real processes and know that
13328 // we won't trample on them any more.
13329 mProcessesReady = true;
13332 Slog.i(TAG, "System now ready");
13333 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13334 SystemClock.uptimeMillis());
13336 synchronized(this) {
13337 // Make sure we have no pre-ready processes sitting around.
13339 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13340 ResolveInfo ri = mContext.getPackageManager()
13341 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13343 CharSequence errorMsg = null;
13345 ActivityInfo ai = ri.activityInfo;
13346 ApplicationInfo app = ai.applicationInfo;
13347 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13348 mTopAction = Intent.ACTION_FACTORY_TEST;
13350 mTopComponent = new ComponentName(app.packageName,
13353 errorMsg = mContext.getResources().getText(
13354 com.android.internal.R.string.factorytest_not_system);
13357 errorMsg = mContext.getResources().getText(
13358 com.android.internal.R.string.factorytest_no_action);
13360 if (errorMsg != null) {
13363 mTopComponent = null;
13364 Message msg = Message.obtain();
13365 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13366 msg.getData().putCharSequence("msg", errorMsg);
13367 mUiHandler.sendMessage(msg);
13372 retrieveSettings();
13373 final int currentUserId;
13374 synchronized (this) {
13375 currentUserId = mUserController.getCurrentUserIdLocked();
13376 readGrantedUriPermissionsLocked();
13379 if (goingCallback != null) goingCallback.run();
13381 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13382 Integer.toString(currentUserId), currentUserId);
13383 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13384 Integer.toString(currentUserId), currentUserId);
13385 mSystemServiceManager.startUser(currentUserId);
13387 synchronized (this) {
13388 // Only start up encryption-aware persistent apps; once user is
13389 // unlocked we'll come back around and start unaware apps
13390 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13392 // Start up initial activity.
13394 // Enable home activity for system user, so that the system can always boot
13395 if (UserManager.isSplitSystemUser()) {
13396 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13398 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13399 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13400 UserHandle.USER_SYSTEM);
13401 } catch (RemoteException e) {
13402 throw e.rethrowAsRuntimeException();
13405 startHomeActivityLocked(currentUserId, "systemReady");
13408 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13409 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13410 + " data partition or your device will be unstable.");
13411 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13413 } catch (RemoteException e) {
13416 if (!Build.isBuildConsistent()) {
13417 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13418 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13421 long ident = Binder.clearCallingIdentity();
13423 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13424 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13425 | Intent.FLAG_RECEIVER_FOREGROUND);
13426 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13427 broadcastIntentLocked(null, null, intent,
13428 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13429 null, false, false, MY_PID, Process.SYSTEM_UID,
13431 intent = new Intent(Intent.ACTION_USER_STARTING);
13432 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13433 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13434 broadcastIntentLocked(null, null, intent,
13435 null, new IIntentReceiver.Stub() {
13437 public void performReceive(Intent intent, int resultCode, String data,
13438 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13439 throws RemoteException {
13442 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13443 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13444 } catch (Throwable t) {
13445 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13447 Binder.restoreCallingIdentity(ident);
13449 mStackSupervisor.resumeFocusedStackTopActivityLocked();
13450 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13454 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13455 synchronized (this) {
13456 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13460 void skipCurrentReceiverLocked(ProcessRecord app) {
13461 for (BroadcastQueue queue : mBroadcastQueues) {
13462 queue.skipCurrentReceiverLocked(app);
13467 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13468 * The application process will exit immediately after this call returns.
13469 * @param app object of the crashing app, null for the system server
13470 * @param crashInfo describing the exception
13472 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13473 ProcessRecord r = findAppProcess(app, "Crash");
13474 final String processName = app == null ? "system_server"
13475 : (r == null ? "unknown" : r.processName);
13477 handleApplicationCrashInner("crash", r, processName, crashInfo);
13480 /* Native crash reporting uses this inner version because it needs to be somewhat
13481 * decoupled from the AM-managed cleanup lifecycle
13483 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13484 ApplicationErrorReport.CrashInfo crashInfo) {
13485 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13486 UserHandle.getUserId(Binder.getCallingUid()), processName,
13487 r == null ? -1 : r.info.flags,
13488 crashInfo.exceptionClassName,
13489 crashInfo.exceptionMessage,
13490 crashInfo.throwFileName,
13491 crashInfo.throwLineNumber);
13493 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13495 mAppErrors.crashApplication(r, crashInfo);
13498 public void handleApplicationStrictModeViolation(
13501 StrictMode.ViolationInfo info) {
13502 ProcessRecord r = findAppProcess(app, "StrictMode");
13507 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13508 Integer stackFingerprint = info.hashCode();
13509 boolean logIt = true;
13510 synchronized (mAlreadyLoggedViolatedStacks) {
13511 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13513 // TODO: sub-sample into EventLog for these, with
13514 // the info.durationMillis? Then we'd get
13515 // the relative pain numbers, without logging all
13516 // the stack traces repeatedly. We'd want to do
13517 // likewise in the client code, which also does
13518 // dup suppression, before the Binder call.
13520 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13521 mAlreadyLoggedViolatedStacks.clear();
13523 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13527 logStrictModeViolationToDropBox(r, info);
13531 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13532 AppErrorResult result = new AppErrorResult();
13533 synchronized (this) {
13534 final long origId = Binder.clearCallingIdentity();
13536 Message msg = Message.obtain();
13537 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13538 HashMap<String, Object> data = new HashMap<String, Object>();
13539 data.put("result", result);
13540 data.put("app", r);
13541 data.put("violationMask", violationMask);
13542 data.put("info", info);
13544 mUiHandler.sendMessage(msg);
13546 Binder.restoreCallingIdentity(origId);
13548 int res = result.get();
13549 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13553 // Depending on the policy in effect, there could be a bunch of
13554 // these in quick succession so we try to batch these together to
13555 // minimize disk writes, number of dropbox entries, and maximize
13556 // compression, by having more fewer, larger records.
13557 private void logStrictModeViolationToDropBox(
13558 ProcessRecord process,
13559 StrictMode.ViolationInfo info) {
13560 if (info == null) {
13563 final boolean isSystemApp = process == null ||
13564 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13565 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13566 final String processName = process == null ? "unknown" : process.processName;
13567 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13568 final DropBoxManager dbox = (DropBoxManager)
13569 mContext.getSystemService(Context.DROPBOX_SERVICE);
13571 // Exit early if the dropbox isn't configured to accept this report type.
13572 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13574 boolean bufferWasEmpty;
13575 boolean needsFlush;
13576 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13577 synchronized (sb) {
13578 bufferWasEmpty = sb.length() == 0;
13579 appendDropBoxProcessHeaders(process, processName, sb);
13580 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13581 sb.append("System-App: ").append(isSystemApp).append("\n");
13582 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13583 if (info.violationNumThisLoop != 0) {
13584 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13586 if (info.numAnimationsRunning != 0) {
13587 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13589 if (info.broadcastIntentAction != null) {
13590 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13592 if (info.durationMillis != -1) {
13593 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13595 if (info.numInstances != -1) {
13596 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13598 if (info.tags != null) {
13599 for (String tag : info.tags) {
13600 sb.append("Span-Tag: ").append(tag).append("\n");
13604 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13605 sb.append(info.crashInfo.stackTrace);
13608 if (info.message != null) {
13609 sb.append(info.message);
13613 // Only buffer up to ~64k. Various logging bits truncate
13615 needsFlush = (sb.length() > 64 * 1024);
13618 // Flush immediately if the buffer's grown too large, or this
13619 // is a non-system app. Non-system apps are isolated with a
13620 // different tag & policy and not batched.
13622 // Batching is useful during internal testing with
13623 // StrictMode settings turned up high. Without batching,
13624 // thousands of separate files could be created on boot.
13625 if (!isSystemApp || needsFlush) {
13626 new Thread("Error dump: " + dropboxTag) {
13628 public void run() {
13630 synchronized (sb) {
13631 report = sb.toString();
13632 sb.delete(0, sb.length());
13635 if (report.length() != 0) {
13636 dbox.addText(dropboxTag, report);
13643 // System app batching:
13644 if (!bufferWasEmpty) {
13645 // An existing dropbox-writing thread is outstanding, so
13646 // we don't need to start it up. The existing thread will
13647 // catch the buffer appends we just did.
13651 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13652 // (After this point, we shouldn't access AMS internal data structures.)
13653 new Thread("Error dump: " + dropboxTag) {
13655 public void run() {
13656 // 5 second sleep to let stacks arrive and be batched together
13658 Thread.sleep(5000); // 5 seconds
13659 } catch (InterruptedException e) {}
13661 String errorReport;
13662 synchronized (mStrictModeBuffer) {
13663 errorReport = mStrictModeBuffer.toString();
13664 if (errorReport.length() == 0) {
13667 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13668 mStrictModeBuffer.trimToSize();
13670 dbox.addText(dropboxTag, errorReport);
13676 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13677 * @param app object of the crashing app, null for the system server
13678 * @param tag reported by the caller
13679 * @param system whether this wtf is coming from the system
13680 * @param crashInfo describing the context of the error
13681 * @return true if the process should exit immediately (WTF is fatal)
13683 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13684 final ApplicationErrorReport.CrashInfo crashInfo) {
13685 final int callingUid = Binder.getCallingUid();
13686 final int callingPid = Binder.getCallingPid();
13689 // If this is coming from the system, we could very well have low-level
13690 // system locks held, so we want to do this all asynchronously. And we
13691 // never want this to become fatal, so there is that too.
13692 mHandler.post(new Runnable() {
13693 @Override public void run() {
13694 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13700 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13703 if (r != null && r.pid != Process.myPid() &&
13704 Settings.Global.getInt(mContext.getContentResolver(),
13705 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13706 mAppErrors.crashApplication(r, crashInfo);
13713 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13714 final ApplicationErrorReport.CrashInfo crashInfo) {
13715 final ProcessRecord r = findAppProcess(app, "WTF");
13716 final String processName = app == null ? "system_server"
13717 : (r == null ? "unknown" : r.processName);
13719 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13720 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13722 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13728 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13729 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13731 private ProcessRecord findAppProcess(IBinder app, String reason) {
13736 synchronized (this) {
13737 final int NP = mProcessNames.getMap().size();
13738 for (int ip=0; ip<NP; ip++) {
13739 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13740 final int NA = apps.size();
13741 for (int ia=0; ia<NA; ia++) {
13742 ProcessRecord p = apps.valueAt(ia);
13743 if (p.thread != null && p.thread.asBinder() == app) {
13749 Slog.w(TAG, "Can't find mystery application for " + reason
13750 + " from pid=" + Binder.getCallingPid()
13751 + " uid=" + Binder.getCallingUid() + ": " + app);
13757 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13758 * to append various headers to the dropbox log text.
13760 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13761 StringBuilder sb) {
13762 // Watchdog thread ends up invoking this function (with
13763 // a null ProcessRecord) to add the stack file to dropbox.
13764 // Do not acquire a lock on this (am) in such cases, as it
13765 // could cause a potential deadlock, if and when watchdog
13766 // is invoked due to unavailability of lock on am and it
13767 // would prevent watchdog from killing system_server.
13768 if (process == null) {
13769 sb.append("Process: ").append(processName).append("\n");
13772 // Note: ProcessRecord 'process' is guarded by the service
13773 // instance. (notably process.pkgList, which could otherwise change
13774 // concurrently during execution of this method)
13775 synchronized (this) {
13776 sb.append("Process: ").append(processName).append("\n");
13777 int flags = process.info.flags;
13778 IPackageManager pm = AppGlobals.getPackageManager();
13779 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13780 for (int ip=0; ip<process.pkgList.size(); ip++) {
13781 String pkg = process.pkgList.keyAt(ip);
13782 sb.append("Package: ").append(pkg);
13784 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13786 sb.append(" v").append(pi.versionCode);
13787 if (pi.versionName != null) {
13788 sb.append(" (").append(pi.versionName).append(")");
13791 } catch (RemoteException e) {
13792 Slog.e(TAG, "Error getting package info: " + pkg, e);
13799 private static String processClass(ProcessRecord process) {
13800 if (process == null || process.pid == MY_PID) {
13801 return "system_server";
13802 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13803 return "system_app";
13809 private volatile long mWtfClusterStart;
13810 private volatile int mWtfClusterCount;
13813 * Write a description of an error (crash, WTF, ANR) to the drop box.
13814 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13815 * @param process which caused the error, null means the system server
13816 * @param activity which triggered the error, null if unknown
13817 * @param parent activity related to the error, null if unknown
13818 * @param subject line related to the error, null if absent
13819 * @param report in long form describing the error, null if absent
13820 * @param dataFile text file to include in the report, null if none
13821 * @param crashInfo giving an application stack trace, null if absent
13823 public void addErrorToDropBox(String eventType,
13824 ProcessRecord process, String processName, ActivityRecord activity,
13825 ActivityRecord parent, String subject,
13826 final String report, final File dataFile,
13827 final ApplicationErrorReport.CrashInfo crashInfo) {
13828 // NOTE -- this must never acquire the ActivityManagerService lock,
13829 // otherwise the watchdog may be prevented from resetting the system.
13831 final String dropboxTag = processClass(process) + "_" + eventType;
13832 final DropBoxManager dbox = (DropBoxManager)
13833 mContext.getSystemService(Context.DROPBOX_SERVICE);
13835 // Exit early if the dropbox isn't configured to accept this report type.
13836 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13838 // Rate-limit how often we're willing to do the heavy lifting below to
13839 // collect and record logs; currently 5 logs per 10 second period.
13840 final long now = SystemClock.elapsedRealtime();
13841 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13842 mWtfClusterStart = now;
13843 mWtfClusterCount = 1;
13845 if (mWtfClusterCount++ >= 5) return;
13848 final StringBuilder sb = new StringBuilder(1024);
13849 appendDropBoxProcessHeaders(process, processName, sb);
13850 if (process != null) {
13851 sb.append("Foreground: ")
13852 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13855 if (activity != null) {
13856 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13858 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13859 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13861 if (parent != null && parent != activity) {
13862 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13864 if (subject != null) {
13865 sb.append("Subject: ").append(subject).append("\n");
13867 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13868 if (Debug.isDebuggerConnected()) {
13869 sb.append("Debugger: Connected\n");
13873 // Do the rest in a worker thread to avoid blocking the caller on I/O
13874 // (After this point, we shouldn't access AMS internal data structures.)
13875 Thread worker = new Thread("Error dump: " + dropboxTag) {
13877 public void run() {
13878 if (report != null) {
13882 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13883 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13884 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13885 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13887 if (dataFile != null && maxDataFileSize > 0) {
13889 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13890 "\n\n[[TRUNCATED]]"));
13891 } catch (IOException e) {
13892 Slog.e(TAG, "Error reading " + dataFile, e);
13895 if (crashInfo != null && crashInfo.stackTrace != null) {
13896 sb.append(crashInfo.stackTrace);
13902 // Merge several logcat streams, and take the last N lines
13903 InputStreamReader input = null;
13905 java.lang.Process logcat = new ProcessBuilder(
13906 "/system/bin/timeout", "-k", "15s", "10s",
13907 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13908 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13909 .redirectErrorStream(true).start();
13911 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13912 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13913 input = new InputStreamReader(logcat.getInputStream());
13916 char[] buf = new char[8192];
13917 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13918 } catch (IOException e) {
13919 Slog.e(TAG, "Error running logcat", e);
13921 if (input != null) try { input.close(); } catch (IOException e) {}
13925 dbox.addText(dropboxTag, sb.toString());
13929 if (process == null) {
13930 // If process is null, we are being called from some internal code
13931 // and may be about to die -- run this synchronously.
13939 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13940 enforceNotIsolatedCaller("getProcessesInErrorState");
13941 // assume our apps are happy - lazy create the list
13942 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13944 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13945 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13946 int userId = UserHandle.getUserId(Binder.getCallingUid());
13948 synchronized (this) {
13950 // iterate across all processes
13951 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13952 ProcessRecord app = mLruProcesses.get(i);
13953 if (!allUsers && app.userId != userId) {
13956 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13957 // This one's in trouble, so we'll generate a report for it
13958 // crashes are higher priority (in case there's a crash *and* an anr)
13959 ActivityManager.ProcessErrorStateInfo report = null;
13960 if (app.crashing) {
13961 report = app.crashingReport;
13962 } else if (app.notResponding) {
13963 report = app.notRespondingReport;
13966 if (report != null) {
13967 if (errList == null) {
13968 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13970 errList.add(report);
13972 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13973 " crashing = " + app.crashing +
13974 " notResponding = " + app.notResponding);
13983 static int procStateToImportance(int procState, int memAdj,
13984 ActivityManager.RunningAppProcessInfo currApp) {
13985 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13986 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13987 currApp.lru = memAdj;
13994 private void fillInProcMemInfo(ProcessRecord app,
13995 ActivityManager.RunningAppProcessInfo outInfo) {
13996 outInfo.pid = app.pid;
13997 outInfo.uid = app.info.uid;
13998 if (mHeavyWeightProcess == app) {
13999 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14001 if (app.persistent) {
14002 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14004 if (app.activities.size() > 0) {
14005 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14007 outInfo.lastTrimLevel = app.trimMemoryLevel;
14008 int adj = app.curAdj;
14009 int procState = app.curProcState;
14010 outInfo.importance = procStateToImportance(procState, adj, outInfo);
14011 outInfo.importanceReasonCode = app.adjTypeCode;
14012 outInfo.processState = app.curProcState;
14016 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14017 enforceNotIsolatedCaller("getRunningAppProcesses");
14019 final int callingUid = Binder.getCallingUid();
14021 // Lazy instantiation of list
14022 List<ActivityManager.RunningAppProcessInfo> runList = null;
14023 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14024 callingUid) == PackageManager.PERMISSION_GRANTED;
14025 final int userId = UserHandle.getUserId(callingUid);
14026 final boolean allUids = isGetTasksAllowed(
14027 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14029 synchronized (this) {
14030 // Iterate across all processes
14031 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14032 ProcessRecord app = mLruProcesses.get(i);
14033 if ((!allUsers && app.userId != userId)
14034 || (!allUids && app.uid != callingUid)) {
14037 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14038 // Generate process state info for running application
14039 ActivityManager.RunningAppProcessInfo currApp =
14040 new ActivityManager.RunningAppProcessInfo(app.processName,
14041 app.pid, app.getPackageList());
14042 fillInProcMemInfo(app, currApp);
14043 if (app.adjSource instanceof ProcessRecord) {
14044 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14045 currApp.importanceReasonImportance =
14046 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14047 app.adjSourceProcState);
14048 } else if (app.adjSource instanceof ActivityRecord) {
14049 ActivityRecord r = (ActivityRecord)app.adjSource;
14050 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14052 if (app.adjTarget instanceof ComponentName) {
14053 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14055 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14056 // + " lru=" + currApp.lru);
14057 if (runList == null) {
14058 runList = new ArrayList<>();
14060 runList.add(currApp);
14068 public List<ApplicationInfo> getRunningExternalApplications() {
14069 enforceNotIsolatedCaller("getRunningExternalApplications");
14070 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14071 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14072 if (runningApps != null && runningApps.size() > 0) {
14073 Set<String> extList = new HashSet<String>();
14074 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14075 if (app.pkgList != null) {
14076 for (String pkg : app.pkgList) {
14081 IPackageManager pm = AppGlobals.getPackageManager();
14082 for (String pkg : extList) {
14084 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14085 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14088 } catch (RemoteException e) {
14096 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14097 enforceNotIsolatedCaller("getMyMemoryState");
14098 synchronized (this) {
14099 ProcessRecord proc;
14100 synchronized (mPidsSelfLocked) {
14101 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14103 fillInProcMemInfo(proc, outInfo);
14108 public int getMemoryTrimLevel() {
14109 enforceNotIsolatedCaller("getMyMemoryState");
14110 synchronized (this) {
14111 return mLastMemoryLevel;
14116 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14117 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14118 (new ActivityManagerShellCommand(this, false)).exec(
14119 this, in, out, err, args, resultReceiver);
14123 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14124 if (checkCallingPermission(android.Manifest.permission.DUMP)
14125 != PackageManager.PERMISSION_GRANTED) {
14126 pw.println("Permission Denial: can't dump ActivityManager from from pid="
14127 + Binder.getCallingPid()
14128 + ", uid=" + Binder.getCallingUid()
14129 + " without permission "
14130 + android.Manifest.permission.DUMP);
14134 boolean dumpAll = false;
14135 boolean dumpClient = false;
14136 boolean dumpCheckin = false;
14137 boolean dumpCheckinFormat = false;
14138 String dumpPackage = null;
14141 while (opti < args.length) {
14142 String opt = args[opti];
14143 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14147 if ("-a".equals(opt)) {
14149 } else if ("-c".equals(opt)) {
14151 } else if ("-p".equals(opt)) {
14152 if (opti < args.length) {
14153 dumpPackage = args[opti];
14156 pw.println("Error: -p option requires package argument");
14160 } else if ("--checkin".equals(opt)) {
14161 dumpCheckin = dumpCheckinFormat = true;
14162 } else if ("-C".equals(opt)) {
14163 dumpCheckinFormat = true;
14164 } else if ("-h".equals(opt)) {
14165 ActivityManagerShellCommand.dumpHelp(pw, true);
14168 pw.println("Unknown argument: " + opt + "; use -h for help");
14172 long origId = Binder.clearCallingIdentity();
14173 boolean more = false;
14174 // Is the caller requesting to dump a particular piece of data?
14175 if (opti < args.length) {
14176 String cmd = args[opti];
14178 if ("activities".equals(cmd) || "a".equals(cmd)) {
14179 synchronized (this) {
14180 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14182 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14183 synchronized (this) {
14184 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14186 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14189 if (opti >= args.length) {
14191 newArgs = EMPTY_STRING_ARRAY;
14193 dumpPackage = args[opti];
14195 newArgs = new String[args.length - opti];
14196 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14197 args.length - opti);
14199 synchronized (this) {
14200 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14202 } else if ("broadcast-stats".equals(cmd)) {
14205 if (opti >= args.length) {
14207 newArgs = EMPTY_STRING_ARRAY;
14209 dumpPackage = args[opti];
14211 newArgs = new String[args.length - opti];
14212 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14213 args.length - opti);
14215 synchronized (this) {
14216 if (dumpCheckinFormat) {
14217 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14220 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14223 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14226 if (opti >= args.length) {
14228 newArgs = EMPTY_STRING_ARRAY;
14230 dumpPackage = args[opti];
14232 newArgs = new String[args.length - opti];
14233 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14234 args.length - opti);
14236 synchronized (this) {
14237 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14239 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14242 if (opti >= args.length) {
14244 newArgs = EMPTY_STRING_ARRAY;
14246 dumpPackage = args[opti];
14248 newArgs = new String[args.length - opti];
14249 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14250 args.length - opti);
14252 synchronized (this) {
14253 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14255 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14256 synchronized (this) {
14257 dumpOomLocked(fd, pw, args, opti, true);
14259 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14260 synchronized (this) {
14261 dumpPermissionsLocked(fd, pw, args, opti, true, null);
14263 } else if ("provider".equals(cmd)) {
14266 if (opti >= args.length) {
14268 newArgs = EMPTY_STRING_ARRAY;
14272 newArgs = new String[args.length - opti];
14273 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14275 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14276 pw.println("No providers match: " + name);
14277 pw.println("Use -h for help.");
14279 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14280 synchronized (this) {
14281 dumpProvidersLocked(fd, pw, args, opti, true, null);
14283 } else if ("service".equals(cmd)) {
14286 if (opti >= args.length) {
14288 newArgs = EMPTY_STRING_ARRAY;
14292 newArgs = new String[args.length - opti];
14293 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14294 args.length - opti);
14296 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14297 pw.println("No services match: " + name);
14298 pw.println("Use -h for help.");
14300 } else if ("package".equals(cmd)) {
14302 if (opti >= args.length) {
14303 pw.println("package: no package name specified");
14304 pw.println("Use -h for help.");
14306 dumpPackage = args[opti];
14308 newArgs = new String[args.length - opti];
14309 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14310 args.length - opti);
14315 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14316 synchronized (this) {
14317 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14319 } else if ("services".equals(cmd) || "s".equals(cmd)) {
14321 ActiveServices.ServiceDumper dumper;
14322 synchronized (this) {
14323 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14326 dumper.dumpWithClient();
14328 synchronized (this) {
14329 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14330 dumpPackage).dumpLocked();
14333 } else if ("locks".equals(cmd)) {
14334 LockGuard.dump(fd, pw, args);
14336 // Dumping a single activity?
14337 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14338 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14339 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14341 pw.println("Bad activity command, or no activities match: " + cmd);
14342 pw.println("Use -h for help.");
14347 Binder.restoreCallingIdentity(origId);
14352 // No piece of data specified, dump everything.
14353 if (dumpCheckinFormat) {
14354 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14355 } else if (dumpClient) {
14356 ActiveServices.ServiceDumper sdumper;
14357 synchronized (this) {
14358 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14361 pw.println("-------------------------------------------------------------------------------");
14363 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14366 pw.println("-------------------------------------------------------------------------------");
14368 if (dumpAll || dumpPackage != null) {
14369 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14372 pw.println("-------------------------------------------------------------------------------");
14375 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14378 pw.println("-------------------------------------------------------------------------------");
14380 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14383 pw.println("-------------------------------------------------------------------------------");
14385 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14388 sdumper.dumpWithClient();
14390 synchronized (this) {
14392 pw.println("-------------------------------------------------------------------------------");
14394 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14397 pw.println("-------------------------------------------------------------------------------");
14399 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14400 if (mAssociations.size() > 0) {
14403 pw.println("-------------------------------------------------------------------------------");
14405 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14409 pw.println("-------------------------------------------------------------------------------");
14411 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14415 synchronized (this) {
14416 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14419 pw.println("-------------------------------------------------------------------------------");
14421 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14424 pw.println("-------------------------------------------------------------------------------");
14426 if (dumpAll || dumpPackage != null) {
14427 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14430 pw.println("-------------------------------------------------------------------------------");
14433 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14436 pw.println("-------------------------------------------------------------------------------");
14438 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14441 pw.println("-------------------------------------------------------------------------------");
14443 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14447 pw.println("-------------------------------------------------------------------------------");
14449 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14452 pw.println("-------------------------------------------------------------------------------");
14454 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14455 if (mAssociations.size() > 0) {
14458 pw.println("-------------------------------------------------------------------------------");
14460 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14464 pw.println("-------------------------------------------------------------------------------");
14466 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14469 Binder.restoreCallingIdentity(origId);
14472 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14473 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14474 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14476 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14478 boolean needSep = printedAnything;
14480 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14481 dumpPackage, needSep, " mFocusedActivity: ");
14483 printedAnything = true;
14487 if (dumpPackage == null) {
14492 printedAnything = true;
14493 mStackSupervisor.dump(pw, " ");
14496 if (!printedAnything) {
14497 pw.println(" (nothing)");
14501 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14502 int opti, boolean dumpAll, String dumpPackage) {
14503 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14505 boolean printedAnything = false;
14507 if (mRecentTasks != null && mRecentTasks.size() > 0) {
14508 boolean printedHeader = false;
14510 final int N = mRecentTasks.size();
14511 for (int i=0; i<N; i++) {
14512 TaskRecord tr = mRecentTasks.get(i);
14513 if (dumpPackage != null) {
14514 if (tr.realActivity == null ||
14515 !dumpPackage.equals(tr.realActivity)) {
14519 if (!printedHeader) {
14520 pw.println(" Recent tasks:");
14521 printedHeader = true;
14522 printedAnything = true;
14524 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
14527 mRecentTasks.get(i).dump(pw, " ");
14532 if (!printedAnything) {
14533 pw.println(" (nothing)");
14537 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14538 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14539 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14542 if (dumpPackage != null) {
14543 IPackageManager pm = AppGlobals.getPackageManager();
14545 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14546 } catch (RemoteException e) {
14550 boolean printedAnything = false;
14552 final long now = SystemClock.uptimeMillis();
14554 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14555 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14556 = mAssociations.valueAt(i1);
14557 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14558 SparseArray<ArrayMap<String, Association>> sourceUids
14559 = targetComponents.valueAt(i2);
14560 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14561 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14562 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14563 Association ass = sourceProcesses.valueAt(i4);
14564 if (dumpPackage != null) {
14565 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14566 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14570 printedAnything = true;
14572 pw.print(ass.mTargetProcess);
14574 UserHandle.formatUid(pw, ass.mTargetUid);
14576 pw.print(ass.mSourceProcess);
14578 UserHandle.formatUid(pw, ass.mSourceUid);
14581 pw.print(ass.mTargetComponent.flattenToShortString());
14584 long dur = ass.mTime;
14585 if (ass.mNesting > 0) {
14586 dur += now - ass.mStartTime;
14588 TimeUtils.formatDuration(dur, pw);
14590 pw.print(ass.mCount);
14591 pw.print(" times)");
14593 for (int i=0; i<ass.mStateTimes.length; i++) {
14594 long amt = ass.mStateTimes[i];
14595 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14596 amt += now - ass.mLastStateUptime;
14600 pw.print(ProcessList.makeProcStateString(
14601 i + ActivityManager.MIN_PROCESS_STATE));
14603 TimeUtils.formatDuration(amt, pw);
14604 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14610 if (ass.mNesting > 0) {
14611 pw.print(" Currently active: ");
14612 TimeUtils.formatDuration(now - ass.mStartTime, pw);
14621 if (!printedAnything) {
14622 pw.println(" (nothing)");
14626 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14627 String header, boolean needSep) {
14628 boolean printed = false;
14629 int whichAppId = -1;
14630 if (dumpPackage != null) {
14632 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14634 whichAppId = UserHandle.getAppId(info.uid);
14635 } catch (NameNotFoundException e) {
14636 e.printStackTrace();
14639 for (int i=0; i<uids.size(); i++) {
14640 UidRecord uidRec = uids.valueAt(i);
14641 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14650 pw.println(header);
14653 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14654 pw.print(": "); pw.println(uidRec);
14659 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14660 int opti, boolean dumpAll, String dumpPackage) {
14661 boolean needSep = false;
14662 boolean printedAnything = false;
14665 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14668 final int NP = mProcessNames.getMap().size();
14669 for (int ip=0; ip<NP; ip++) {
14670 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14671 final int NA = procs.size();
14672 for (int ia=0; ia<NA; ia++) {
14673 ProcessRecord r = procs.valueAt(ia);
14674 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14678 pw.println(" All known processes:");
14680 printedAnything = true;
14682 pw.print(r.persistent ? " *PERS*" : " *APP*");
14683 pw.print(" UID "); pw.print(procs.keyAt(ia));
14684 pw.print(" "); pw.println(r);
14686 if (r.persistent) {
14693 if (mIsolatedProcesses.size() > 0) {
14694 boolean printed = false;
14695 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14696 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14697 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14704 pw.println(" Isolated process list (sorted by uid):");
14705 printedAnything = true;
14709 pw.println(String.format("%sIsolated #%2d: %s",
14710 " ", i, r.toString()));
14714 if (mActiveUids.size() > 0) {
14715 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14716 printedAnything = needSep = true;
14719 if (mValidateUids.size() > 0) {
14720 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14721 printedAnything = needSep = true;
14725 if (mLruProcesses.size() > 0) {
14729 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14730 pw.print(" total, non-act at ");
14731 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14732 pw.print(", non-svc at ");
14733 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14735 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14737 printedAnything = true;
14740 if (dumpAll || dumpPackage != null) {
14741 synchronized (mPidsSelfLocked) {
14742 boolean printed = false;
14743 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14744 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14745 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14749 if (needSep) pw.println();
14751 pw.println(" PID mappings:");
14753 printedAnything = true;
14755 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14756 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14761 if (mForegroundProcesses.size() > 0) {
14762 synchronized (mPidsSelfLocked) {
14763 boolean printed = false;
14764 for (int i=0; i<mForegroundProcesses.size(); i++) {
14765 ProcessRecord r = mPidsSelfLocked.get(
14766 mForegroundProcesses.valueAt(i).pid);
14767 if (dumpPackage != null && (r == null
14768 || !r.pkgList.containsKey(dumpPackage))) {
14772 if (needSep) pw.println();
14774 pw.println(" Foreground Processes:");
14776 printedAnything = true;
14778 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14779 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14784 if (mPersistentStartingProcesses.size() > 0) {
14785 if (needSep) pw.println();
14787 printedAnything = true;
14788 pw.println(" Persisent processes that are starting:");
14789 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14790 "Starting Norm", "Restarting PERS", dumpPackage);
14793 if (mRemovedProcesses.size() > 0) {
14794 if (needSep) pw.println();
14796 printedAnything = true;
14797 pw.println(" Processes that are being removed:");
14798 dumpProcessList(pw, this, mRemovedProcesses, " ",
14799 "Removed Norm", "Removed PERS", dumpPackage);
14802 if (mProcessesOnHold.size() > 0) {
14803 if (needSep) pw.println();
14805 printedAnything = true;
14806 pw.println(" Processes that are on old until the system is ready:");
14807 dumpProcessList(pw, this, mProcessesOnHold, " ",
14808 "OnHold Norm", "OnHold PERS", dumpPackage);
14811 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14813 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14815 printedAnything = true;
14818 if (dumpPackage == null) {
14821 mUserController.dump(pw, dumpAll);
14823 if (mHomeProcess != null && (dumpPackage == null
14824 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14829 pw.println(" mHomeProcess: " + mHomeProcess);
14831 if (mPreviousProcess != null && (dumpPackage == null
14832 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14837 pw.println(" mPreviousProcess: " + mPreviousProcess);
14840 StringBuilder sb = new StringBuilder(128);
14841 sb.append(" mPreviousProcessVisibleTime: ");
14842 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14845 if (mHeavyWeightProcess != null && (dumpPackage == null
14846 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14851 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14853 if (dumpPackage == null) {
14854 pw.println(" mConfiguration: " + mConfiguration);
14857 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14858 if (mCompatModePackages.getPackages().size() > 0) {
14859 boolean printed = false;
14860 for (Map.Entry<String, Integer> entry
14861 : mCompatModePackages.getPackages().entrySet()) {
14862 String pkg = entry.getKey();
14863 int mode = entry.getValue();
14864 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14868 pw.println(" mScreenCompatPackages:");
14871 pw.print(" "); pw.print(pkg); pw.print(": ");
14872 pw.print(mode); pw.println();
14876 if (dumpPackage == null) {
14877 pw.println(" mWakefulness="
14878 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14879 pw.println(" mSleepTokens=" + mSleepTokens);
14880 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14881 + lockScreenShownToString());
14882 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14883 if (mRunningVoice != null) {
14884 pw.println(" mRunningVoice=" + mRunningVoice);
14885 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14888 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14889 || mOrigWaitForDebugger) {
14890 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14891 || dumpPackage.equals(mOrigDebugApp)) {
14896 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14897 + " mDebugTransient=" + mDebugTransient
14898 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14901 if (mCurAppTimeTracker != null) {
14902 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14904 if (mMemWatchProcesses.getMap().size() > 0) {
14905 pw.println(" Mem watch processes:");
14906 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14907 = mMemWatchProcesses.getMap();
14908 for (int i=0; i<procs.size(); i++) {
14909 final String proc = procs.keyAt(i);
14910 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14911 for (int j=0; j<uids.size(); j++) {
14916 StringBuilder sb = new StringBuilder();
14917 sb.append(" ").append(proc).append('/');
14918 UserHandle.formatUid(sb, uids.keyAt(j));
14919 Pair<Long, String> val = uids.valueAt(j);
14920 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14921 if (val.second != null) {
14922 sb.append(", report to ").append(val.second);
14924 pw.println(sb.toString());
14927 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14928 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14929 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14930 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14932 if (mTrackAllocationApp != null) {
14933 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14938 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14941 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14942 || mProfileFd != null) {
14943 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14948 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14949 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14950 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14951 + mAutoStopProfiler);
14952 pw.println(" mProfileType=" + mProfileType);
14955 if (mNativeDebuggingApp != null) {
14956 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14961 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14964 if (dumpPackage == null) {
14965 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14966 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14967 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14969 if (mController != null) {
14970 pw.println(" mController=" + mController
14971 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14974 pw.println(" Total persistent processes: " + numPers);
14975 pw.println(" mProcessesReady=" + mProcessesReady
14976 + " mSystemReady=" + mSystemReady
14977 + " mBooted=" + mBooted
14978 + " mFactoryTest=" + mFactoryTest);
14979 pw.println(" mBooting=" + mBooting
14980 + " mCallFinishBooting=" + mCallFinishBooting
14981 + " mBootAnimationComplete=" + mBootAnimationComplete);
14982 pw.print(" mLastPowerCheckRealtime=");
14983 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14985 pw.print(" mLastPowerCheckUptime=");
14986 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14988 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14989 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14990 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14991 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
14992 + " (" + mLruProcesses.size() + " total)"
14993 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14994 + " mNumServiceProcs=" + mNumServiceProcs
14995 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14996 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
14997 + " mLastMemoryLevel=" + mLastMemoryLevel
14998 + " mLastNumProcesses=" + mLastNumProcesses);
14999 long now = SystemClock.uptimeMillis();
15000 pw.print(" mLastIdleTime=");
15001 TimeUtils.formatDuration(now, mLastIdleTime, pw);
15002 pw.print(" mLowRamSinceLastIdle=");
15003 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15008 if (!printedAnything) {
15009 pw.println(" (nothing)");
15013 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15014 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15015 if (mProcessesToGc.size() > 0) {
15016 boolean printed = false;
15017 long now = SystemClock.uptimeMillis();
15018 for (int i=0; i<mProcessesToGc.size(); i++) {
15019 ProcessRecord proc = mProcessesToGc.get(i);
15020 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15024 if (needSep) pw.println();
15026 pw.println(" Processes that are waiting to GC:");
15029 pw.print(" Process "); pw.println(proc);
15030 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
15031 pw.print(", last gced=");
15032 pw.print(now-proc.lastRequestedGc);
15033 pw.print(" ms ago, last lowMem=");
15034 pw.print(now-proc.lastLowMemory);
15035 pw.println(" ms ago");
15042 void printOomLevel(PrintWriter pw, String name, int adj) {
15046 if (adj < 10) pw.print(' ');
15048 if (adj > -10) pw.print(' ');
15054 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15058 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15059 int opti, boolean dumpAll) {
15060 boolean needSep = false;
15062 if (mLruProcesses.size() > 0) {
15063 if (needSep) pw.println();
15065 pw.println(" OOM levels:");
15066 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15067 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15068 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15069 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15070 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15071 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15072 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15073 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15074 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15075 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15076 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15077 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15078 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15079 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15081 if (needSep) pw.println();
15082 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
15083 pw.print(" total, non-act at ");
15084 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15085 pw.print(", non-svc at ");
15086 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15088 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
15092 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15095 pw.println(" mHomeProcess: " + mHomeProcess);
15096 pw.println(" mPreviousProcess: " + mPreviousProcess);
15097 if (mHeavyWeightProcess != null) {
15098 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15105 * There are three ways to call this:
15106 * - no provider specified: dump all the providers
15107 * - a flattened component name that matched an existing provider was specified as the
15108 * first arg: dump that one provider
15109 * - the first arg isn't the flattened component name of an existing provider:
15110 * dump all providers whose component contains the first arg as a substring
15112 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15113 int opti, boolean dumpAll) {
15114 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15117 static class ItemMatcher {
15118 ArrayList<ComponentName> components;
15119 ArrayList<String> strings;
15120 ArrayList<Integer> objects;
15127 void build(String name) {
15128 ComponentName componentName = ComponentName.unflattenFromString(name);
15129 if (componentName != null) {
15130 if (components == null) {
15131 components = new ArrayList<ComponentName>();
15133 components.add(componentName);
15137 // Not a '/' separated full component name; maybe an object ID?
15139 objectId = Integer.parseInt(name, 16);
15140 if (objects == null) {
15141 objects = new ArrayList<Integer>();
15143 objects.add(objectId);
15145 } catch (RuntimeException e) {
15146 // Not an integer; just do string match.
15147 if (strings == null) {
15148 strings = new ArrayList<String>();
15156 int build(String[] args, int opti) {
15157 for (; opti<args.length; opti++) {
15158 String name = args[opti];
15159 if ("--".equals(name)) {
15167 boolean match(Object object, ComponentName comp) {
15171 if (components != null) {
15172 for (int i=0; i<components.size(); i++) {
15173 if (components.get(i).equals(comp)) {
15178 if (objects != null) {
15179 for (int i=0; i<objects.size(); i++) {
15180 if (System.identityHashCode(object) == objects.get(i)) {
15185 if (strings != null) {
15186 String flat = comp.flattenToString();
15187 for (int i=0; i<strings.size(); i++) {
15188 if (flat.contains(strings.get(i))) {
15198 * There are three things that cmd can be:
15199 * - a flattened component name that matches an existing activity
15200 * - the cmd arg isn't the flattened component name of an existing activity:
15201 * dump all activity whose component contains the cmd as a substring
15202 * - A hex number of the ActivityRecord object instance.
15204 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15205 int opti, boolean dumpAll) {
15206 ArrayList<ActivityRecord> activities;
15208 synchronized (this) {
15209 activities = mStackSupervisor.getDumpActivitiesLocked(name);
15212 if (activities.size() <= 0) {
15216 String[] newArgs = new String[args.length - opti];
15217 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15219 TaskRecord lastTask = null;
15220 boolean needSep = false;
15221 for (int i=activities.size()-1; i>=0; i--) {
15222 ActivityRecord r = activities.get(i);
15227 synchronized (this) {
15228 if (lastTask != r.task) {
15230 pw.print("TASK "); pw.print(lastTask.affinity);
15231 pw.print(" id="); pw.println(lastTask.taskId);
15233 lastTask.dump(pw, " ");
15237 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
15243 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15244 * there is a thread associated with the activity.
15246 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15247 final ActivityRecord r, String[] args, boolean dumpAll) {
15248 String innerPrefix = prefix + " ";
15249 synchronized (this) {
15250 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15251 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15253 if (r.app != null) pw.println(r.app.pid);
15254 else pw.println("(not running)");
15256 r.dump(pw, innerPrefix);
15259 if (r.app != null && r.app.thread != null) {
15260 // flush anything that is already in the PrintWriter since the thread is going
15261 // to write to the file descriptor directly
15264 TransferPipe tp = new TransferPipe();
15266 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15267 r.appToken, innerPrefix, args);
15272 } catch (IOException e) {
15273 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15274 } catch (RemoteException e) {
15275 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15280 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15281 int opti, boolean dumpAll, String dumpPackage) {
15282 boolean needSep = false;
15283 boolean onlyHistory = false;
15284 boolean printedAnything = false;
15286 if ("history".equals(dumpPackage)) {
15287 if (opti < args.length && "-s".equals(args[opti])) {
15290 onlyHistory = true;
15291 dumpPackage = null;
15294 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15295 if (!onlyHistory && dumpAll) {
15296 if (mRegisteredReceivers.size() > 0) {
15297 boolean printed = false;
15298 Iterator it = mRegisteredReceivers.values().iterator();
15299 while (it.hasNext()) {
15300 ReceiverList r = (ReceiverList)it.next();
15301 if (dumpPackage != null && (r.app == null ||
15302 !dumpPackage.equals(r.app.info.packageName))) {
15306 pw.println(" Registered Receivers:");
15309 printedAnything = true;
15311 pw.print(" * "); pw.println(r);
15316 if (mReceiverResolver.dump(pw, needSep ?
15317 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
15318 " ", dumpPackage, false, false)) {
15320 printedAnything = true;
15324 for (BroadcastQueue q : mBroadcastQueues) {
15325 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15326 printedAnything |= needSep;
15331 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15332 for (int user=0; user<mStickyBroadcasts.size(); user++) {
15337 printedAnything = true;
15338 pw.print(" Sticky broadcasts for user ");
15339 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15340 StringBuilder sb = new StringBuilder(128);
15341 for (Map.Entry<String, ArrayList<Intent>> ent
15342 : mStickyBroadcasts.valueAt(user).entrySet()) {
15343 pw.print(" * Sticky action "); pw.print(ent.getKey());
15346 ArrayList<Intent> intents = ent.getValue();
15347 final int N = intents.size();
15348 for (int i=0; i<N; i++) {
15350 sb.append(" Intent: ");
15351 intents.get(i).toShortString(sb, false, true, false, false);
15352 pw.println(sb.toString());
15353 Bundle bundle = intents.get(i).getExtras();
15354 if (bundle != null) {
15356 pw.println(bundle.toString());
15366 if (!onlyHistory && dumpAll) {
15368 for (BroadcastQueue queue : mBroadcastQueues) {
15369 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
15370 + queue.mBroadcastsScheduled);
15372 pw.println(" mHandler:");
15373 mHandler.dump(new PrintWriterPrinter(pw), " ");
15375 printedAnything = true;
15378 if (!printedAnything) {
15379 pw.println(" (nothing)");
15383 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15384 int opti, boolean dumpAll, String dumpPackage) {
15385 if (mCurBroadcastStats == null) {
15389 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15390 final long now = SystemClock.elapsedRealtime();
15391 if (mLastBroadcastStats != null) {
15392 pw.print(" Last stats (from ");
15393 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15395 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15397 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15398 - mLastBroadcastStats.mStartUptime, pw);
15399 pw.println(" uptime):");
15400 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15401 pw.println(" (nothing)");
15405 pw.print(" Current stats (from ");
15406 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15407 pw.print(" to now, ");
15408 TimeUtils.formatDuration(SystemClock.uptimeMillis()
15409 - mCurBroadcastStats.mStartUptime, pw);
15410 pw.println(" uptime):");
15411 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15412 pw.println(" (nothing)");
15416 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15417 int opti, boolean fullCheckin, String dumpPackage) {
15418 if (mCurBroadcastStats == null) {
15422 if (mLastBroadcastStats != null) {
15423 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15425 mLastBroadcastStats = null;
15429 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15431 mCurBroadcastStats = null;
15435 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15436 int opti, boolean dumpAll, String dumpPackage) {
15438 boolean printedAnything = false;
15440 ItemMatcher matcher = new ItemMatcher();
15441 matcher.build(args, opti);
15443 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15445 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15446 printedAnything |= needSep;
15448 if (mLaunchingProviders.size() > 0) {
15449 boolean printed = false;
15450 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15451 ContentProviderRecord r = mLaunchingProviders.get(i);
15452 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15456 if (needSep) pw.println();
15458 pw.println(" Launching content providers:");
15460 printedAnything = true;
15462 pw.print(" Launching #"); pw.print(i); pw.print(": ");
15467 if (!printedAnything) {
15468 pw.println(" (nothing)");
15472 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15473 int opti, boolean dumpAll, String dumpPackage) {
15474 boolean needSep = false;
15475 boolean printedAnything = false;
15477 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15479 if (mGrantedUriPermissions.size() > 0) {
15480 boolean printed = false;
15482 if (dumpPackage != null) {
15484 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15485 MATCH_UNINSTALLED_PACKAGES, 0);
15486 } catch (NameNotFoundException e) {
15490 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15491 int uid = mGrantedUriPermissions.keyAt(i);
15492 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15495 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15497 if (needSep) pw.println();
15499 pw.println(" Granted Uri Permissions:");
15501 printedAnything = true;
15503 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
15504 for (UriPermission perm : perms.values()) {
15505 pw.print(" "); pw.println(perm);
15507 perm.dump(pw, " ");
15513 if (!printedAnything) {
15514 pw.println(" (nothing)");
15518 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15519 int opti, boolean dumpAll, String dumpPackage) {
15520 boolean printed = false;
15522 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15524 if (mIntentSenderRecords.size() > 0) {
15525 Iterator<WeakReference<PendingIntentRecord>> it
15526 = mIntentSenderRecords.values().iterator();
15527 while (it.hasNext()) {
15528 WeakReference<PendingIntentRecord> ref = it.next();
15529 PendingIntentRecord rec = ref != null ? ref.get(): null;
15530 if (dumpPackage != null && (rec == null
15531 || !dumpPackage.equals(rec.key.packageName))) {
15536 pw.print(" * "); pw.println(rec);
15541 pw.print(" * "); pw.println(ref);
15547 pw.println(" (nothing)");
15551 private static final int dumpProcessList(PrintWriter pw,
15552 ActivityManagerService service, List list,
15553 String prefix, String normalLabel, String persistentLabel,
15554 String dumpPackage) {
15556 final int N = list.size()-1;
15557 for (int i=N; i>=0; i--) {
15558 ProcessRecord r = (ProcessRecord)list.get(i);
15559 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15562 pw.println(String.format("%s%s #%2d: %s",
15563 prefix, (r.persistent ? persistentLabel : normalLabel),
15565 if (r.persistent) {
15572 private static final boolean dumpProcessOomList(PrintWriter pw,
15573 ActivityManagerService service, List<ProcessRecord> origList,
15574 String prefix, String normalLabel, String persistentLabel,
15575 boolean inclDetails, String dumpPackage) {
15577 ArrayList<Pair<ProcessRecord, Integer>> list
15578 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15579 for (int i=0; i<origList.size(); i++) {
15580 ProcessRecord r = origList.get(i);
15581 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15584 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15587 if (list.size() <= 0) {
15591 Comparator<Pair<ProcessRecord, Integer>> comparator
15592 = new Comparator<Pair<ProcessRecord, Integer>>() {
15594 public int compare(Pair<ProcessRecord, Integer> object1,
15595 Pair<ProcessRecord, Integer> object2) {
15596 if (object1.first.setAdj != object2.first.setAdj) {
15597 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15599 if (object1.first.setProcState != object2.first.setProcState) {
15600 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15602 if (object1.second.intValue() != object2.second.intValue()) {
15603 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15609 Collections.sort(list, comparator);
15611 final long curRealtime = SystemClock.elapsedRealtime();
15612 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15613 final long curUptime = SystemClock.uptimeMillis();
15614 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15616 for (int i=list.size()-1; i>=0; i--) {
15617 ProcessRecord r = list.get(i).first;
15618 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15620 switch (r.setSchedGroup) {
15621 case ProcessList.SCHED_GROUP_BACKGROUND:
15624 case ProcessList.SCHED_GROUP_DEFAULT:
15627 case ProcessList.SCHED_GROUP_TOP_APP:
15635 if (r.foregroundActivities) {
15637 } else if (r.foregroundServices) {
15642 String procState = ProcessList.makeProcStateString(r.curProcState);
15644 pw.print(r.persistent ? persistentLabel : normalLabel);
15646 int num = (origList.size()-1)-list.get(i).second;
15647 if (num < 10) pw.print(' ');
15652 pw.print(schedGroup);
15654 pw.print(foreground);
15656 pw.print(procState);
15658 if (r.trimMemoryLevel < 10) pw.print(' ');
15659 pw.print(r.trimMemoryLevel);
15661 pw.print(r.toShortString());
15663 pw.print(r.adjType);
15665 if (r.adjSource != null || r.adjTarget != null) {
15668 if (r.adjTarget instanceof ComponentName) {
15669 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15670 } else if (r.adjTarget != null) {
15671 pw.print(r.adjTarget.toString());
15673 pw.print("{null}");
15676 if (r.adjSource instanceof ProcessRecord) {
15678 pw.print(((ProcessRecord)r.adjSource).toShortString());
15680 } else if (r.adjSource != null) {
15681 pw.println(r.adjSource.toString());
15683 pw.println("{null}");
15689 pw.print("oom: max="); pw.print(r.maxAdj);
15690 pw.print(" curRaw="); pw.print(r.curRawAdj);
15691 pw.print(" setRaw="); pw.print(r.setRawAdj);
15692 pw.print(" cur="); pw.print(r.curAdj);
15693 pw.print(" set="); pw.println(r.setAdj);
15696 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15697 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15698 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15699 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15700 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15704 pw.print("cached="); pw.print(r.cached);
15705 pw.print(" empty="); pw.print(r.empty);
15706 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15708 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15709 if (r.lastWakeTime != 0) {
15711 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15712 synchronized (stats) {
15713 wtime = stats.getProcessWakeTime(r.info.uid,
15714 r.pid, curRealtime);
15716 long timeUsed = wtime - r.lastWakeTime;
15719 pw.print("keep awake over ");
15720 TimeUtils.formatDuration(realtimeSince, pw);
15721 pw.print(" used ");
15722 TimeUtils.formatDuration(timeUsed, pw);
15724 pw.print((timeUsed*100)/realtimeSince);
15727 if (r.lastCpuTime != 0) {
15728 long timeUsed = r.curCpuTime - r.lastCpuTime;
15731 pw.print("run cpu over ");
15732 TimeUtils.formatDuration(uptimeSince, pw);
15733 pw.print(" used ");
15734 TimeUtils.formatDuration(timeUsed, pw);
15736 pw.print((timeUsed*100)/uptimeSince);
15745 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15747 ArrayList<ProcessRecord> procs;
15748 synchronized (this) {
15749 if (args != null && args.length > start
15750 && args[start].charAt(0) != '-') {
15751 procs = new ArrayList<ProcessRecord>();
15754 pid = Integer.parseInt(args[start]);
15755 } catch (NumberFormatException e) {
15757 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15758 ProcessRecord proc = mLruProcesses.get(i);
15759 if (proc.pid == pid) {
15761 } else if (allPkgs && proc.pkgList != null
15762 && proc.pkgList.containsKey(args[start])) {
15764 } else if (proc.processName.equals(args[start])) {
15768 if (procs.size() <= 0) {
15772 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15778 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15779 PrintWriter pw, String[] args) {
15780 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15781 if (procs == null) {
15782 pw.println("No process found for: " + args[0]);
15786 long uptime = SystemClock.uptimeMillis();
15787 long realtime = SystemClock.elapsedRealtime();
15788 pw.println("Applications Graphics Acceleration Info:");
15789 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15791 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15792 ProcessRecord r = procs.get(i);
15793 if (r.thread != null) {
15794 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15797 TransferPipe tp = new TransferPipe();
15799 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15804 } catch (IOException e) {
15805 pw.println("Failure while dumping the app: " + r);
15807 } catch (RemoteException e) {
15808 pw.println("Got a RemoteException while dumping the app " + r);
15815 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15816 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15817 if (procs == null) {
15818 pw.println("No process found for: " + args[0]);
15822 pw.println("Applications Database Info:");
15824 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15825 ProcessRecord r = procs.get(i);
15826 if (r.thread != null) {
15827 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15830 TransferPipe tp = new TransferPipe();
15832 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15837 } catch (IOException e) {
15838 pw.println("Failure while dumping the app: " + r);
15840 } catch (RemoteException e) {
15841 pw.println("Got a RemoteException while dumping the app " + r);
15848 final static class MemItem {
15849 final boolean isProc;
15850 final String label;
15851 final String shortLabel;
15853 final long swapPss;
15855 final boolean hasActivities;
15856 ArrayList<MemItem> subitems;
15858 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15859 boolean _hasActivities) {
15862 shortLabel = _shortLabel;
15864 swapPss = _swapPss;
15866 hasActivities = _hasActivities;
15869 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15872 shortLabel = _shortLabel;
15874 swapPss = _swapPss;
15876 hasActivities = false;
15880 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15881 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15882 if (sort && !isCompact) {
15883 Collections.sort(items, new Comparator<MemItem>() {
15885 public int compare(MemItem lhs, MemItem rhs) {
15886 if (lhs.pss < rhs.pss) {
15888 } else if (lhs.pss > rhs.pss) {
15896 for (int i=0; i<items.size(); i++) {
15897 MemItem mi = items.get(i);
15900 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15901 mi.label, stringifyKBSize(mi.swapPss));
15903 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15905 } else if (mi.isProc) {
15906 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15907 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15908 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15909 pw.println(mi.hasActivities ? ",a" : ",e");
15911 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15912 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15914 if (mi.subitems != null) {
15915 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15916 true, isCompact, dumpSwapPss);
15921 // These are in KB.
15922 static final long[] DUMP_MEM_BUCKETS = new long[] {
15923 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15924 120*1024, 160*1024, 200*1024,
15925 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15926 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15929 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15930 boolean stackLike) {
15931 int start = label.lastIndexOf('.');
15932 if (start >= 0) start++;
15934 int end = label.length();
15935 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15936 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15937 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15938 out.append(bucket);
15939 out.append(stackLike ? "MB." : "MB ");
15940 out.append(label, start, end);
15944 out.append(memKB/1024);
15945 out.append(stackLike ? "MB." : "MB ");
15946 out.append(label, start, end);
15949 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15950 ProcessList.NATIVE_ADJ,
15951 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15952 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15953 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15954 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15955 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15956 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15958 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15960 "System", "Persistent", "Persistent Service", "Foreground",
15961 "Visible", "Perceptible",
15962 "Heavy Weight", "Backup",
15963 "A Services", "Home",
15964 "Previous", "B Services", "Cached"
15966 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15968 "sys", "pers", "persvc", "fore",
15971 "servicea", "home",
15972 "prev", "serviceb", "cached"
15975 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15976 long realtime, boolean isCheckinRequest, boolean isCompact) {
15978 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15980 if (isCheckinRequest || isCompact) {
15981 // short checkin version
15982 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15984 pw.println("Applications Memory Usage (in Kilobytes):");
15985 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15989 private static final int KSM_SHARED = 0;
15990 private static final int KSM_SHARING = 1;
15991 private static final int KSM_UNSHARED = 2;
15992 private static final int KSM_VOLATILE = 3;
15994 private final long[] getKsmInfo() {
15995 long[] longOut = new long[4];
15996 final int[] SINGLE_LONG_FORMAT = new int[] {
15997 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15999 long[] longTmp = new long[1];
16000 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16001 SINGLE_LONG_FORMAT, null, longTmp, null);
16002 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16004 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16005 SINGLE_LONG_FORMAT, null, longTmp, null);
16006 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16008 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16009 SINGLE_LONG_FORMAT, null, longTmp, null);
16010 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16012 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16013 SINGLE_LONG_FORMAT, null, longTmp, null);
16014 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16018 private static String stringifySize(long size, int order) {
16019 Locale locale = Locale.US;
16022 return String.format(locale, "%,13d", size);
16024 return String.format(locale, "%,9dK", size / 1024);
16026 return String.format(locale, "%,5dM", size / 1024 / 1024);
16027 case 1024 * 1024 * 1024:
16028 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16030 throw new IllegalArgumentException("Invalid size order");
16034 private static String stringifyKBSize(long size) {
16035 return stringifySize(size * 1024, 1024);
16038 // Update this version number in case you change the 'compact' format
16039 private static final int MEMINFO_COMPACT_VERSION = 1;
16041 final void dumpApplicationMemoryUsage(FileDescriptor fd,
16042 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16043 boolean dumpDetails = false;
16044 boolean dumpFullDetails = false;
16045 boolean dumpDalvik = false;
16046 boolean dumpSummaryOnly = false;
16047 boolean dumpUnreachable = false;
16048 boolean oomOnly = false;
16049 boolean isCompact = false;
16050 boolean localOnly = false;
16051 boolean packages = false;
16052 boolean isCheckinRequest = false;
16053 boolean dumpSwapPss = false;
16056 while (opti < args.length) {
16057 String opt = args[opti];
16058 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16062 if ("-a".equals(opt)) {
16063 dumpDetails = true;
16064 dumpFullDetails = true;
16066 dumpSwapPss = true;
16067 } else if ("-d".equals(opt)) {
16069 } else if ("-c".equals(opt)) {
16071 } else if ("-s".equals(opt)) {
16072 dumpDetails = true;
16073 dumpSummaryOnly = true;
16074 } else if ("-S".equals(opt)) {
16075 dumpSwapPss = true;
16076 } else if ("--unreachable".equals(opt)) {
16077 dumpUnreachable = true;
16078 } else if ("--oom".equals(opt)) {
16080 } else if ("--local".equals(opt)) {
16082 } else if ("--package".equals(opt)) {
16084 } else if ("--checkin".equals(opt)) {
16085 isCheckinRequest = true;
16087 } else if ("-h".equals(opt)) {
16088 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16089 pw.println(" -a: include all available information for each process.");
16090 pw.println(" -d: include dalvik details.");
16091 pw.println(" -c: dump in a compact machine-parseable representation.");
16092 pw.println(" -s: dump only summary of application memory usage.");
16093 pw.println(" -S: dump also SwapPss.");
16094 pw.println(" --oom: only show processes organized by oom adj.");
16095 pw.println(" --local: only collect details locally, don't call process.");
16096 pw.println(" --package: interpret process arg as package, dumping all");
16097 pw.println(" processes that have loaded that package.");
16098 pw.println(" --checkin: dump data for a checkin");
16099 pw.println("If [process] is specified it can be the name or ");
16100 pw.println("pid of a specific process to dump.");
16103 pw.println("Unknown argument: " + opt + "; use -h for help");
16107 long uptime = SystemClock.uptimeMillis();
16108 long realtime = SystemClock.elapsedRealtime();
16109 final long[] tmpLong = new long[1];
16111 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16112 if (procs == null) {
16113 // No Java processes. Maybe they want to print a native process.
16114 if (args != null && args.length > opti
16115 && args[opti].charAt(0) != '-') {
16116 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16117 = new ArrayList<ProcessCpuTracker.Stats>();
16118 updateCpuStatsNow();
16121 findPid = Integer.parseInt(args[opti]);
16122 } catch (NumberFormatException e) {
16124 synchronized (mProcessCpuTracker) {
16125 final int N = mProcessCpuTracker.countStats();
16126 for (int i=0; i<N; i++) {
16127 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16128 if (st.pid == findPid || (st.baseName != null
16129 && st.baseName.equals(args[opti]))) {
16130 nativeProcs.add(st);
16134 if (nativeProcs.size() > 0) {
16135 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16137 Debug.MemoryInfo mi = null;
16138 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16139 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16140 final int pid = r.pid;
16141 if (!isCheckinRequest && dumpDetails) {
16142 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16145 mi = new Debug.MemoryInfo();
16147 if (dumpDetails || (!brief && !oomOnly)) {
16148 Debug.getMemoryInfo(pid, mi);
16150 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16151 mi.dalvikPrivateDirty = (int)tmpLong[0];
16153 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16154 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16155 if (isCheckinRequest) {
16162 pw.println("No process found for: " + args[opti]);
16166 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16167 dumpDetails = true;
16170 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16172 String[] innerArgs = new String[args.length-opti];
16173 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16175 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16176 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16177 long nativePss = 0;
16178 long nativeSwapPss = 0;
16179 long dalvikPss = 0;
16180 long dalvikSwapPss = 0;
16181 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16183 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16186 long otherSwapPss = 0;
16187 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16188 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16190 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16191 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16192 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16193 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16196 long totalSwapPss = 0;
16197 long cachedPss = 0;
16198 long cachedSwapPss = 0;
16199 boolean hasSwapPss = false;
16201 Debug.MemoryInfo mi = null;
16202 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16203 final ProcessRecord r = procs.get(i);
16204 final IApplicationThread thread;
16207 final boolean hasActivities;
16208 synchronized (this) {
16211 oomAdj = r.getSetAdjWithServices();
16212 hasActivities = r.activities.size() > 0;
16214 if (thread != null) {
16215 if (!isCheckinRequest && dumpDetails) {
16216 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16219 mi = new Debug.MemoryInfo();
16221 if (dumpDetails || (!brief && !oomOnly)) {
16222 Debug.getMemoryInfo(pid, mi);
16223 hasSwapPss = mi.hasSwappedOutPss;
16225 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16226 mi.dalvikPrivateDirty = (int)tmpLong[0];
16230 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16231 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16232 if (isCheckinRequest) {
16238 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16239 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16240 } catch (RemoteException e) {
16241 if (!isCheckinRequest) {
16242 pw.println("Got RemoteException!");
16249 final long myTotalPss = mi.getTotalPss();
16250 final long myTotalUss = mi.getTotalUss();
16251 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16253 synchronized (this) {
16254 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16255 // Record this for posterity if the process has been stable.
16256 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16260 if (!isCheckinRequest && mi != null) {
16261 totalPss += myTotalPss;
16262 totalSwapPss += myTotalSwapPss;
16263 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16264 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16265 myTotalSwapPss, pid, hasActivities);
16266 procMems.add(pssItem);
16267 procMemsMap.put(pid, pssItem);
16269 nativePss += mi.nativePss;
16270 nativeSwapPss += mi.nativeSwappedOutPss;
16271 dalvikPss += mi.dalvikPss;
16272 dalvikSwapPss += mi.dalvikSwappedOutPss;
16273 for (int j=0; j<dalvikSubitemPss.length; j++) {
16274 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16275 dalvikSubitemSwapPss[j] +=
16276 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16278 otherPss += mi.otherPss;
16279 otherSwapPss += mi.otherSwappedOutPss;
16280 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16281 long mem = mi.getOtherPss(j);
16284 mem = mi.getOtherSwappedOutPss(j);
16285 miscSwapPss[j] += mem;
16286 otherSwapPss -= mem;
16289 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16290 cachedPss += myTotalPss;
16291 cachedSwapPss += myTotalSwapPss;
16294 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16295 if (oomIndex == (oomPss.length - 1)
16296 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16297 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16298 oomPss[oomIndex] += myTotalPss;
16299 oomSwapPss[oomIndex] += myTotalSwapPss;
16300 if (oomProcs[oomIndex] == null) {
16301 oomProcs[oomIndex] = new ArrayList<MemItem>();
16303 oomProcs[oomIndex].add(pssItem);
16311 long nativeProcTotalPss = 0;
16313 if (!isCheckinRequest && procs.size() > 1 && !packages) {
16314 // If we are showing aggregations, also look for native processes to
16315 // include so that our aggregations are more accurate.
16316 updateCpuStatsNow();
16318 synchronized (mProcessCpuTracker) {
16319 final int N = mProcessCpuTracker.countStats();
16320 for (int i=0; i<N; i++) {
16321 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16322 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16324 mi = new Debug.MemoryInfo();
16326 if (!brief && !oomOnly) {
16327 Debug.getMemoryInfo(st.pid, mi);
16329 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16330 mi.nativePrivateDirty = (int)tmpLong[0];
16333 final long myTotalPss = mi.getTotalPss();
16334 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16335 totalPss += myTotalPss;
16336 nativeProcTotalPss += myTotalPss;
16338 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16339 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16340 procMems.add(pssItem);
16342 nativePss += mi.nativePss;
16343 nativeSwapPss += mi.nativeSwappedOutPss;
16344 dalvikPss += mi.dalvikPss;
16345 dalvikSwapPss += mi.dalvikSwappedOutPss;
16346 for (int j=0; j<dalvikSubitemPss.length; j++) {
16347 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16348 dalvikSubitemSwapPss[j] +=
16349 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16351 otherPss += mi.otherPss;
16352 otherSwapPss += mi.otherSwappedOutPss;
16353 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16354 long mem = mi.getOtherPss(j);
16357 mem = mi.getOtherSwappedOutPss(j);
16358 miscSwapPss[j] += mem;
16359 otherSwapPss -= mem;
16361 oomPss[0] += myTotalPss;
16362 oomSwapPss[0] += myTotalSwapPss;
16363 if (oomProcs[0] == null) {
16364 oomProcs[0] = new ArrayList<MemItem>();
16366 oomProcs[0].add(pssItem);
16371 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16373 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16374 final MemItem dalvikItem =
16375 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16376 if (dalvikSubitemPss.length > 0) {
16377 dalvikItem.subitems = new ArrayList<MemItem>();
16378 for (int j=0; j<dalvikSubitemPss.length; j++) {
16379 final String name = Debug.MemoryInfo.getOtherLabel(
16380 Debug.MemoryInfo.NUM_OTHER_STATS + j);
16381 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16382 dalvikSubitemSwapPss[j], j));
16385 catMems.add(dalvikItem);
16386 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16387 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16388 String label = Debug.MemoryInfo.getOtherLabel(j);
16389 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16392 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16393 for (int j=0; j<oomPss.length; j++) {
16394 if (oomPss[j] != 0) {
16395 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16396 : DUMP_MEM_OOM_LABEL[j];
16397 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16398 DUMP_MEM_OOM_ADJ[j]);
16399 item.subitems = oomProcs[j];
16404 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16405 if (!brief && !oomOnly && !isCompact) {
16407 pw.println("Total PSS by process:");
16408 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
16412 pw.println("Total PSS by OOM adjustment:");
16414 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
16415 if (!brief && !oomOnly) {
16416 PrintWriter out = categoryPw != null ? categoryPw : pw;
16419 out.println("Total PSS by category:");
16421 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
16426 MemInfoReader memInfo = new MemInfoReader();
16427 memInfo.readMemInfo();
16428 if (nativeProcTotalPss > 0) {
16429 synchronized (this) {
16430 final long cachedKb = memInfo.getCachedSizeKb();
16431 final long freeKb = memInfo.getFreeSizeKb();
16432 final long zramKb = memInfo.getZramTotalSizeKb();
16433 final long kernelKb = memInfo.getKernelUsedSizeKb();
16434 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16435 kernelKb*1024, nativeProcTotalPss*1024);
16436 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16437 nativeProcTotalPss);
16442 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16443 pw.print(" (status ");
16444 switch (mLastMemoryLevel) {
16445 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16446 pw.println("normal)");
16448 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16449 pw.println("moderate)");
16451 case ProcessStats.ADJ_MEM_FACTOR_LOW:
16452 pw.println("low)");
16454 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16455 pw.println("critical)");
16458 pw.print(mLastMemoryLevel);
16462 pw.print(" Free RAM: ");
16463 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16464 + memInfo.getFreeSizeKb()));
16466 pw.print(stringifyKBSize(cachedPss));
16467 pw.print(" cached pss + ");
16468 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16469 pw.print(" cached kernel + ");
16470 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16471 pw.println(" free)");
16473 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16474 pw.print(cachedPss + memInfo.getCachedSizeKb()
16475 + memInfo.getFreeSizeKb()); pw.print(",");
16476 pw.println(totalPss - cachedPss);
16479 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16480 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16481 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16483 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16484 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16485 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16486 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16487 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16489 pw.print("lostram,"); pw.println(lostRAM);
16492 if (memInfo.getZramTotalSizeKb() != 0) {
16494 pw.print(" ZRAM: ");
16495 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16496 pw.print(" physical used for ");
16497 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16498 - memInfo.getSwapFreeSizeKb()));
16499 pw.print(" in swap (");
16500 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16501 pw.println(" total swap)");
16503 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16504 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16505 pw.println(memInfo.getSwapFreeSizeKb());
16508 final long[] ksm = getKsmInfo();
16510 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16511 || ksm[KSM_VOLATILE] != 0) {
16512 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16513 pw.print(" saved from shared ");
16514 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16515 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16516 pw.print(" unshared; ");
16517 pw.print(stringifyKBSize(
16518 ksm[KSM_VOLATILE])); pw.println(" volatile");
16520 pw.print(" Tuning: ");
16521 pw.print(ActivityManager.staticGetMemoryClass());
16522 pw.print(" (large ");
16523 pw.print(ActivityManager.staticGetLargeMemoryClass());
16524 pw.print("), oom ");
16525 pw.print(stringifySize(
16526 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16527 pw.print(", restore limit ");
16528 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16529 if (ActivityManager.isLowRamDeviceStatic()) {
16530 pw.print(" (low-ram)");
16532 if (ActivityManager.isHighEndGfx()) {
16533 pw.print(" (high-end-gfx)");
16537 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16538 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16539 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16540 pw.print("tuning,");
16541 pw.print(ActivityManager.staticGetMemoryClass());
16543 pw.print(ActivityManager.staticGetLargeMemoryClass());
16545 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16546 if (ActivityManager.isLowRamDeviceStatic()) {
16547 pw.print(",low-ram");
16549 if (ActivityManager.isHighEndGfx()) {
16550 pw.print(",high-end-gfx");
16558 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16559 long memtrack, String name) {
16561 sb.append(ProcessList.makeOomAdjString(oomAdj));
16563 sb.append(ProcessList.makeProcStateString(procState));
16565 ProcessList.appendRamKb(sb, pss);
16568 if (memtrack > 0) {
16570 sb.append(stringifyKBSize(memtrack));
16571 sb.append(" memtrack)");
16575 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16576 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16577 sb.append(" (pid ");
16580 sb.append(mi.adjType);
16582 if (mi.adjReason != null) {
16584 sb.append(mi.adjReason);
16589 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16590 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16591 for (int i=0, N=memInfos.size(); i<N; i++) {
16592 ProcessMemInfo mi = memInfos.get(i);
16593 infoMap.put(mi.pid, mi);
16595 updateCpuStatsNow();
16596 long[] memtrackTmp = new long[1];
16597 final List<ProcessCpuTracker.Stats> stats;
16598 // Get a list of Stats that have vsize > 0
16599 synchronized (mProcessCpuTracker) {
16600 stats = mProcessCpuTracker.getStats((st) -> {
16601 return st.vsize > 0;
16604 final int statsCount = stats.size();
16605 for (int i = 0; i < statsCount; i++) {
16606 ProcessCpuTracker.Stats st = stats.get(i);
16607 long pss = Debug.getPss(st.pid, null, memtrackTmp);
16609 if (infoMap.indexOfKey(st.pid) < 0) {
16610 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16611 ProcessList.NATIVE_ADJ, -1, "native", null);
16613 mi.memtrack = memtrackTmp[0];
16620 long totalMemtrack = 0;
16621 for (int i=0, N=memInfos.size(); i<N; i++) {
16622 ProcessMemInfo mi = memInfos.get(i);
16624 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16625 mi.memtrack = memtrackTmp[0];
16627 totalPss += mi.pss;
16628 totalMemtrack += mi.memtrack;
16630 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16631 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16632 if (lhs.oomAdj != rhs.oomAdj) {
16633 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16635 if (lhs.pss != rhs.pss) {
16636 return lhs.pss < rhs.pss ? 1 : -1;
16642 StringBuilder tag = new StringBuilder(128);
16643 StringBuilder stack = new StringBuilder(128);
16644 tag.append("Low on memory -- ");
16645 appendMemBucket(tag, totalPss, "total", false);
16646 appendMemBucket(stack, totalPss, "total", true);
16648 StringBuilder fullNativeBuilder = new StringBuilder(1024);
16649 StringBuilder shortNativeBuilder = new StringBuilder(1024);
16650 StringBuilder fullJavaBuilder = new StringBuilder(1024);
16652 boolean firstLine = true;
16653 int lastOomAdj = Integer.MIN_VALUE;
16654 long extraNativeRam = 0;
16655 long extraNativeMemtrack = 0;
16656 long cachedPss = 0;
16657 for (int i=0, N=memInfos.size(); i<N; i++) {
16658 ProcessMemInfo mi = memInfos.get(i);
16660 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16661 cachedPss += mi.pss;
16664 if (mi.oomAdj != ProcessList.NATIVE_ADJ
16665 && (mi.oomAdj < ProcessList.SERVICE_ADJ
16666 || mi.oomAdj == ProcessList.HOME_APP_ADJ
16667 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16668 if (lastOomAdj != mi.oomAdj) {
16669 lastOomAdj = mi.oomAdj;
16670 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16673 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16678 stack.append("\n\t at ");
16686 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16687 appendMemBucket(tag, mi.pss, mi.name, false);
16689 appendMemBucket(stack, mi.pss, mi.name, true);
16690 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16691 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16693 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16694 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16695 stack.append(DUMP_MEM_OOM_LABEL[k]);
16697 stack.append(DUMP_MEM_OOM_ADJ[k]);
16704 appendMemInfo(fullNativeBuilder, mi);
16705 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16706 // The short form only has native processes that are >= 512K.
16707 if (mi.pss >= 512) {
16708 appendMemInfo(shortNativeBuilder, mi);
16710 extraNativeRam += mi.pss;
16711 extraNativeMemtrack += mi.memtrack;
16714 // Short form has all other details, but if we have collected RAM
16715 // from smaller native processes let's dump a summary of that.
16716 if (extraNativeRam > 0) {
16717 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16718 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16719 shortNativeBuilder.append('\n');
16720 extraNativeRam = 0;
16722 appendMemInfo(fullJavaBuilder, mi);
16726 fullJavaBuilder.append(" ");
16727 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16728 fullJavaBuilder.append(": TOTAL");
16729 if (totalMemtrack > 0) {
16730 fullJavaBuilder.append(" (");
16731 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16732 fullJavaBuilder.append(" memtrack)");
16735 fullJavaBuilder.append("\n");
16737 MemInfoReader memInfo = new MemInfoReader();
16738 memInfo.readMemInfo();
16739 final long[] infos = memInfo.getRawInfo();
16741 StringBuilder memInfoBuilder = new StringBuilder(1024);
16742 Debug.getMemInfo(infos);
16743 memInfoBuilder.append(" MemInfo: ");
16744 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16745 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16746 memInfoBuilder.append(stringifyKBSize(
16747 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16748 memInfoBuilder.append(stringifyKBSize(
16749 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16750 memInfoBuilder.append(stringifyKBSize(
16751 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16752 memInfoBuilder.append(" ");
16753 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16754 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16755 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16756 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16757 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16758 memInfoBuilder.append(" ZRAM: ");
16759 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16760 memInfoBuilder.append(" RAM, ");
16761 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16762 memInfoBuilder.append(" swap total, ");
16763 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16764 memInfoBuilder.append(" swap free\n");
16766 final long[] ksm = getKsmInfo();
16767 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16768 || ksm[KSM_VOLATILE] != 0) {
16769 memInfoBuilder.append(" KSM: ");
16770 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16771 memInfoBuilder.append(" saved from shared ");
16772 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16773 memInfoBuilder.append("\n ");
16774 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16775 memInfoBuilder.append(" unshared; ");
16776 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16777 memInfoBuilder.append(" volatile\n");
16779 memInfoBuilder.append(" Free RAM: ");
16780 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16781 + memInfo.getFreeSizeKb()));
16782 memInfoBuilder.append("\n");
16783 memInfoBuilder.append(" Used RAM: ");
16784 memInfoBuilder.append(stringifyKBSize(
16785 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16786 memInfoBuilder.append("\n");
16787 memInfoBuilder.append(" Lost RAM: ");
16788 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16789 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16790 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16791 memInfoBuilder.append("\n");
16792 Slog.i(TAG, "Low on memory:");
16793 Slog.i(TAG, shortNativeBuilder.toString());
16794 Slog.i(TAG, fullJavaBuilder.toString());
16795 Slog.i(TAG, memInfoBuilder.toString());
16797 StringBuilder dropBuilder = new StringBuilder(1024);
16799 StringWriter oomSw = new StringWriter();
16800 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16801 StringWriter catSw = new StringWriter();
16802 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16803 String[] emptyArgs = new String[] { };
16804 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16806 String oomString = oomSw.toString();
16808 dropBuilder.append("Low on memory:");
16809 dropBuilder.append(stack);
16810 dropBuilder.append('\n');
16811 dropBuilder.append(fullNativeBuilder);
16812 dropBuilder.append(fullJavaBuilder);
16813 dropBuilder.append('\n');
16814 dropBuilder.append(memInfoBuilder);
16815 dropBuilder.append('\n');
16817 dropBuilder.append(oomString);
16818 dropBuilder.append('\n');
16820 StringWriter catSw = new StringWriter();
16821 synchronized (ActivityManagerService.this) {
16822 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16823 String[] emptyArgs = new String[] { };
16825 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16827 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16828 false, null).dumpLocked();
16830 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16833 dropBuilder.append(catSw.toString());
16834 addErrorToDropBox("lowmem", null, "system_server", null,
16835 null, tag.toString(), dropBuilder.toString(), null, null);
16836 //Slog.i(TAG, "Sent to dropbox:");
16837 //Slog.i(TAG, dropBuilder.toString());
16838 synchronized (ActivityManagerService.this) {
16839 long now = SystemClock.uptimeMillis();
16840 if (mLastMemUsageReportTime < now) {
16841 mLastMemUsageReportTime = now;
16847 * Searches array of arguments for the specified string
16848 * @param args array of argument strings
16849 * @param value value to search for
16850 * @return true if the value is contained in the array
16852 private static boolean scanArgs(String[] args, String value) {
16853 if (args != null) {
16854 for (String arg : args) {
16855 if (value.equals(arg)) {
16863 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16864 ContentProviderRecord cpr, boolean always) {
16865 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16867 if (!inLaunching || always) {
16868 synchronized (cpr) {
16869 cpr.launchingApp = null;
16872 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16873 String names[] = cpr.info.authority.split(";");
16874 for (int j = 0; j < names.length; j++) {
16875 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16879 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16880 ContentProviderConnection conn = cpr.connections.get(i);
16881 if (conn.waiting) {
16882 // If this connection is waiting for the provider, then we don't
16883 // need to mess with its process unless we are always removing
16884 // or for some reason the provider is not currently launching.
16885 if (inLaunching && !always) {
16889 ProcessRecord capp = conn.client;
16891 if (conn.stableCount > 0) {
16892 if (!capp.persistent && capp.thread != null
16894 && capp.pid != MY_PID) {
16895 capp.kill("depends on provider "
16896 + cpr.name.flattenToShortString()
16897 + " in dying proc " + (proc != null ? proc.processName : "??")
16898 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16900 } else if (capp.thread != null && conn.provider.provider != null) {
16902 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16903 } catch (RemoteException e) {
16905 // In the protocol here, we don't expect the client to correctly
16906 // clean up this connection, we'll just remove it.
16907 cpr.connections.remove(i);
16908 if (conn.client.conProviders.remove(conn)) {
16909 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16914 if (inLaunching && always) {
16915 mLaunchingProviders.remove(cpr);
16917 return inLaunching;
16921 * Main code for cleaning up a process when it has gone away. This is
16922 * called both as a result of the process dying, or directly when stopping
16923 * a process when running in single process mode.
16925 * @return Returns true if the given process has been restarted, so the
16926 * app that was passed in must remain on the process lists.
16928 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16929 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16930 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16932 removeLruProcessLocked(app);
16933 ProcessList.remove(app.pid);
16936 mProcessesToGc.remove(app);
16937 mPendingPssProcesses.remove(app);
16939 // Dismiss any open dialogs.
16940 if (app.crashDialog != null && !app.forceCrashReport) {
16941 app.crashDialog.dismiss();
16942 app.crashDialog = null;
16944 if (app.anrDialog != null) {
16945 app.anrDialog.dismiss();
16946 app.anrDialog = null;
16948 if (app.waitDialog != null) {
16949 app.waitDialog.dismiss();
16950 app.waitDialog = null;
16953 app.crashing = false;
16954 app.notResponding = false;
16956 app.resetPackageList(mProcessStats);
16957 app.unlinkDeathRecipient();
16958 app.makeInactive(mProcessStats);
16959 app.waitingToKill = null;
16960 app.forcingToForeground = null;
16961 updateProcessForegroundLocked(app, false, false);
16962 app.foregroundActivities = false;
16963 app.hasShownUi = false;
16964 app.treatLikeActivity = false;
16965 app.hasAboveClient = false;
16966 app.hasClientActivities = false;
16968 mServices.killServicesLocked(app, allowRestart);
16970 boolean restart = false;
16972 // Remove published content providers.
16973 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16974 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16975 final boolean always = app.bad || !allowRestart;
16976 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16977 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16978 // We left the provider in the launching list, need to
16983 cpr.provider = null;
16986 app.pubProviders.clear();
16988 // Take care of any launching providers waiting for this process.
16989 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16993 // Unregister from connected content providers.
16994 if (!app.conProviders.isEmpty()) {
16995 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16996 ContentProviderConnection conn = app.conProviders.get(i);
16997 conn.provider.connections.remove(conn);
16998 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16999 conn.provider.name);
17001 app.conProviders.clear();
17004 // At this point there may be remaining entries in mLaunchingProviders
17005 // where we were the only one waiting, so they are no longer of use.
17006 // Look for these and clean up if found.
17007 // XXX Commented out for now. Trying to figure out a way to reproduce
17008 // the actual situation to identify what is actually going on.
17010 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17011 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17012 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17013 synchronized (cpr) {
17014 cpr.launchingApp = null;
17021 skipCurrentReceiverLocked(app);
17023 // Unregister any receivers.
17024 for (int i = app.receivers.size() - 1; i >= 0; i--) {
17025 removeReceiverLocked(app.receivers.valueAt(i));
17027 app.receivers.clear();
17029 // If the app is undergoing backup, tell the backup manager about it
17030 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17031 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17032 + mBackupTarget.appInfo + " died during backup");
17034 IBackupManager bm = IBackupManager.Stub.asInterface(
17035 ServiceManager.getService(Context.BACKUP_SERVICE));
17036 bm.agentDisconnected(app.info.packageName);
17037 } catch (RemoteException e) {
17038 // can't happen; backup manager is local
17042 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17043 ProcessChangeItem item = mPendingProcessChanges.get(i);
17044 if (item.pid == app.pid) {
17045 mPendingProcessChanges.remove(i);
17046 mAvailProcessChanges.add(item);
17049 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17050 null).sendToTarget();
17052 // If the caller is restarting this app, then leave it in its
17053 // current lists and let the caller take care of it.
17058 if (!app.persistent || app.isolated) {
17059 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17060 "Removing non-persistent process during cleanup: " + app);
17061 if (!replacingPid) {
17062 removeProcessNameLocked(app.processName, app.uid, app);
17064 if (mHeavyWeightProcess == app) {
17065 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17066 mHeavyWeightProcess.userId, 0));
17067 mHeavyWeightProcess = null;
17069 } else if (!app.removed) {
17070 // This app is persistent, so we need to keep its record around.
17071 // If it is not already on the pending app list, add it there
17072 // and start a new process for it.
17073 if (mPersistentStartingProcesses.indexOf(app) < 0) {
17074 mPersistentStartingProcesses.add(app);
17078 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17079 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17080 mProcessesOnHold.remove(app);
17082 if (app == mHomeProcess) {
17083 mHomeProcess = null;
17085 if (app == mPreviousProcess) {
17086 mPreviousProcess = null;
17089 if (restart && !app.isolated) {
17090 // We have components that still need to be running in the
17091 // process, so re-launch it.
17093 ProcessList.remove(app.pid);
17095 addProcessNameLocked(app);
17096 startProcessLocked(app, "restart", app.processName);
17098 } else if (app.pid > 0 && app.pid != MY_PID) {
17101 synchronized (mPidsSelfLocked) {
17102 mPidsSelfLocked.remove(app.pid);
17103 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17105 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17106 if (app.isolated) {
17107 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17114 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17115 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17116 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17117 if (cpr.launchingApp == app) {
17124 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17125 // Look through the content providers we are waiting to have launched,
17126 // and if any run in this process then either schedule a restart of
17127 // the process or kill the client waiting for it if this process has
17129 boolean restart = false;
17130 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17131 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17132 if (cpr.launchingApp == app) {
17133 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17136 removeDyingProviderLocked(app, cpr, true);
17143 // =========================================================
17145 // =========================================================
17148 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17150 enforceNotIsolatedCaller("getServices");
17151 synchronized (this) {
17152 return mServices.getRunningServiceInfoLocked(maxNum, flags);
17157 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17158 enforceNotIsolatedCaller("getRunningServiceControlPanel");
17159 synchronized (this) {
17160 return mServices.getRunningServiceControlPanelLocked(name);
17165 public ComponentName startService(IApplicationThread caller, Intent service,
17166 String resolvedType, String callingPackage, int userId)
17167 throws TransactionTooLargeException {
17168 enforceNotIsolatedCaller("startService");
17169 // Refuse possible leaked file descriptors
17170 if (service != null && service.hasFileDescriptors() == true) {
17171 throw new IllegalArgumentException("File descriptors passed in Intent");
17174 if (callingPackage == null) {
17175 throw new IllegalArgumentException("callingPackage cannot be null");
17178 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17179 "startService: " + service + " type=" + resolvedType);
17180 synchronized(this) {
17181 final int callingPid = Binder.getCallingPid();
17182 final int callingUid = Binder.getCallingUid();
17183 final long origId = Binder.clearCallingIdentity();
17184 ComponentName res = mServices.startServiceLocked(caller, service,
17185 resolvedType, callingPid, callingUid, callingPackage, userId);
17186 Binder.restoreCallingIdentity(origId);
17191 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17192 String callingPackage, int userId)
17193 throws TransactionTooLargeException {
17194 synchronized(this) {
17195 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17196 "startServiceInPackage: " + service + " type=" + resolvedType);
17197 final long origId = Binder.clearCallingIdentity();
17198 ComponentName res = mServices.startServiceLocked(null, service,
17199 resolvedType, -1, uid, callingPackage, userId);
17200 Binder.restoreCallingIdentity(origId);
17206 public int stopService(IApplicationThread caller, Intent service,
17207 String resolvedType, int userId) {
17208 enforceNotIsolatedCaller("stopService");
17209 // Refuse possible leaked file descriptors
17210 if (service != null && service.hasFileDescriptors() == true) {
17211 throw new IllegalArgumentException("File descriptors passed in Intent");
17214 synchronized(this) {
17215 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17220 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17221 enforceNotIsolatedCaller("peekService");
17222 // Refuse possible leaked file descriptors
17223 if (service != null && service.hasFileDescriptors() == true) {
17224 throw new IllegalArgumentException("File descriptors passed in Intent");
17227 if (callingPackage == null) {
17228 throw new IllegalArgumentException("callingPackage cannot be null");
17231 synchronized(this) {
17232 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17237 public boolean stopServiceToken(ComponentName className, IBinder token,
17239 synchronized(this) {
17240 return mServices.stopServiceTokenLocked(className, token, startId);
17245 public void setServiceForeground(ComponentName className, IBinder token,
17246 int id, Notification notification, int flags) {
17247 synchronized(this) {
17248 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17253 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17254 boolean requireFull, String name, String callerPackage) {
17255 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17256 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17259 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17260 String className, int flags) {
17261 boolean result = false;
17262 // For apps that don't have pre-defined UIDs, check for permission
17263 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17264 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17265 if (ActivityManager.checkUidPermission(
17266 INTERACT_ACROSS_USERS,
17267 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17268 ComponentName comp = new ComponentName(aInfo.packageName, className);
17269 String msg = "Permission Denial: Component " + comp.flattenToShortString()
17270 + " requests FLAG_SINGLE_USER, but app does not hold "
17271 + INTERACT_ACROSS_USERS;
17273 throw new SecurityException(msg);
17275 // Permission passed
17278 } else if ("system".equals(componentProcessName)) {
17280 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17281 // Phone app and persistent apps are allowed to export singleuser providers.
17282 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17283 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17285 if (DEBUG_MU) Slog.v(TAG_MU,
17286 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17287 + Integer.toHexString(flags) + ") = " + result);
17292 * Checks to see if the caller is in the same app as the singleton
17293 * component, or the component is in a special app. It allows special apps
17294 * to export singleton components but prevents exporting singleton
17295 * components for regular apps.
17297 boolean isValidSingletonCall(int callingUid, int componentUid) {
17298 int componentAppId = UserHandle.getAppId(componentUid);
17299 return UserHandle.isSameApp(callingUid, componentUid)
17300 || componentAppId == Process.SYSTEM_UID
17301 || componentAppId == Process.PHONE_UID
17302 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17303 == PackageManager.PERMISSION_GRANTED;
17306 public int bindService(IApplicationThread caller, IBinder token, Intent service,
17307 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17308 int userId) throws TransactionTooLargeException {
17309 enforceNotIsolatedCaller("bindService");
17311 // Refuse possible leaked file descriptors
17312 if (service != null && service.hasFileDescriptors() == true) {
17313 throw new IllegalArgumentException("File descriptors passed in Intent");
17316 if (callingPackage == null) {
17317 throw new IllegalArgumentException("callingPackage cannot be null");
17320 synchronized(this) {
17321 return mServices.bindServiceLocked(caller, token, service,
17322 resolvedType, connection, flags, callingPackage, userId);
17326 public boolean unbindService(IServiceConnection connection) {
17327 synchronized (this) {
17328 return mServices.unbindServiceLocked(connection);
17332 public void publishService(IBinder token, Intent intent, IBinder service) {
17333 // Refuse possible leaked file descriptors
17334 if (intent != null && intent.hasFileDescriptors() == true) {
17335 throw new IllegalArgumentException("File descriptors passed in Intent");
17338 synchronized(this) {
17339 if (!(token instanceof ServiceRecord)) {
17340 throw new IllegalArgumentException("Invalid service token");
17342 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17346 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17347 // Refuse possible leaked file descriptors
17348 if (intent != null && intent.hasFileDescriptors() == true) {
17349 throw new IllegalArgumentException("File descriptors passed in Intent");
17352 synchronized(this) {
17353 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17357 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17358 synchronized(this) {
17359 if (!(token instanceof ServiceRecord)) {
17360 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17361 throw new IllegalArgumentException("Invalid service token");
17363 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17367 // =========================================================
17368 // BACKUP AND RESTORE
17369 // =========================================================
17371 // Cause the target app to be launched if necessary and its backup agent
17372 // instantiated. The backup agent will invoke backupAgentCreated() on the
17373 // activity manager to announce its creation.
17374 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17375 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17376 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17378 IPackageManager pm = AppGlobals.getPackageManager();
17379 ApplicationInfo app = null;
17381 app = pm.getApplicationInfo(packageName, 0, userId);
17382 } catch (RemoteException e) {
17383 // can't happen; package manager is process-local
17386 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17390 synchronized(this) {
17391 // !!! TODO: currently no check here that we're already bound
17392 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17393 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17394 synchronized (stats) {
17395 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17398 // Backup agent is now in use, its package can't be stopped.
17400 AppGlobals.getPackageManager().setPackageStoppedState(
17401 app.packageName, false, UserHandle.getUserId(app.uid));
17402 } catch (RemoteException e) {
17403 } catch (IllegalArgumentException e) {
17404 Slog.w(TAG, "Failed trying to unstop package "
17405 + app.packageName + ": " + e);
17408 BackupRecord r = new BackupRecord(ss, app, backupMode);
17409 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17410 ? new ComponentName(app.packageName, app.backupAgentName)
17411 : new ComponentName("android", "FullBackupAgent");
17412 // startProcessLocked() returns existing proc's record if it's already running
17413 ProcessRecord proc = startProcessLocked(app.processName, app,
17414 false, 0, "backup", hostingName, false, false, false);
17415 if (proc == null) {
17416 Slog.e(TAG, "Unable to start backup agent process " + r);
17420 // If the app is a regular app (uid >= 10000) and not the system server or phone
17421 // process, etc, then mark it as being in full backup so that certain calls to the
17422 // process can be blocked. This is not reset to false anywhere because we kill the
17423 // process after the full backup is done and the ProcessRecord will vaporize anyway.
17424 if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17425 proc.inFullBackup = true;
17429 mBackupAppName = app.packageName;
17431 // Try not to kill the process during backup
17432 updateOomAdjLocked(proc);
17434 // If the process is already attached, schedule the creation of the backup agent now.
17435 // If it is not yet live, this will be done when it attaches to the framework.
17436 if (proc.thread != null) {
17437 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17439 proc.thread.scheduleCreateBackupAgent(app,
17440 compatibilityInfoForPackageLocked(app), backupMode);
17441 } catch (RemoteException e) {
17442 // Will time out on the backup manager side
17445 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17447 // Invariants: at this point, the target app process exists and the application
17448 // is either already running or in the process of coming up. mBackupTarget and
17449 // mBackupAppName describe the app, so that when it binds back to the AM we
17450 // know that it's scheduled for a backup-agent operation.
17457 public void clearPendingBackup() {
17458 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17459 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17461 synchronized (this) {
17462 mBackupTarget = null;
17463 mBackupAppName = null;
17467 // A backup agent has just come up
17468 public void backupAgentCreated(String agentPackageName, IBinder agent) {
17469 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17472 synchronized(this) {
17473 if (!agentPackageName.equals(mBackupAppName)) {
17474 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17479 long oldIdent = Binder.clearCallingIdentity();
17481 IBackupManager bm = IBackupManager.Stub.asInterface(
17482 ServiceManager.getService(Context.BACKUP_SERVICE));
17483 bm.agentConnected(agentPackageName, agent);
17484 } catch (RemoteException e) {
17485 // can't happen; the backup manager service is local
17486 } catch (Exception e) {
17487 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17488 e.printStackTrace();
17490 Binder.restoreCallingIdentity(oldIdent);
17494 // done with this agent
17495 public void unbindBackupAgent(ApplicationInfo appInfo) {
17496 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17497 if (appInfo == null) {
17498 Slog.w(TAG, "unbind backup agent for null app");
17502 synchronized(this) {
17504 if (mBackupAppName == null) {
17505 Slog.w(TAG, "Unbinding backup agent with no active backup");
17509 if (!mBackupAppName.equals(appInfo.packageName)) {
17510 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17514 // Not backing this app up any more; reset its OOM adjustment
17515 final ProcessRecord proc = mBackupTarget.app;
17516 updateOomAdjLocked(proc);
17518 // If the app crashed during backup, 'thread' will be null here
17519 if (proc.thread != null) {
17521 proc.thread.scheduleDestroyBackupAgent(appInfo,
17522 compatibilityInfoForPackageLocked(appInfo));
17523 } catch (Exception e) {
17524 Slog.e(TAG, "Exception when unbinding backup agent:");
17525 e.printStackTrace();
17529 mBackupTarget = null;
17530 mBackupAppName = null;
17534 // =========================================================
17536 // =========================================================
17538 boolean isPendingBroadcastProcessLocked(int pid) {
17539 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17540 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17543 void skipPendingBroadcastLocked(int pid) {
17544 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17545 for (BroadcastQueue queue : mBroadcastQueues) {
17546 queue.skipPendingBroadcastLocked(pid);
17550 // The app just attached; send any pending broadcasts that it should receive
17551 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17552 boolean didSomething = false;
17553 for (BroadcastQueue queue : mBroadcastQueues) {
17554 didSomething |= queue.sendPendingBroadcastsLocked(app);
17556 return didSomething;
17559 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17560 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17561 enforceNotIsolatedCaller("registerReceiver");
17562 ArrayList<Intent> stickyIntents = null;
17563 ProcessRecord callerApp = null;
17566 synchronized(this) {
17567 if (caller != null) {
17568 callerApp = getRecordForAppLocked(caller);
17569 if (callerApp == null) {
17570 throw new SecurityException(
17571 "Unable to find app for caller " + caller
17572 + " (pid=" + Binder.getCallingPid()
17573 + ") when registering receiver " + receiver);
17575 if (callerApp.info.uid != Process.SYSTEM_UID &&
17576 !callerApp.pkgList.containsKey(callerPackage) &&
17577 !"android".equals(callerPackage)) {
17578 throw new SecurityException("Given caller package " + callerPackage
17579 + " is not running in process " + callerApp);
17581 callingUid = callerApp.info.uid;
17582 callingPid = callerApp.pid;
17584 callerPackage = null;
17585 callingUid = Binder.getCallingUid();
17586 callingPid = Binder.getCallingPid();
17589 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17590 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17592 Iterator<String> actions = filter.actionsIterator();
17593 if (actions == null) {
17594 ArrayList<String> noAction = new ArrayList<String>(1);
17595 noAction.add(null);
17596 actions = noAction.iterator();
17599 // Collect stickies of users
17600 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17601 while (actions.hasNext()) {
17602 String action = actions.next();
17603 for (int id : userIds) {
17604 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17605 if (stickies != null) {
17606 ArrayList<Intent> intents = stickies.get(action);
17607 if (intents != null) {
17608 if (stickyIntents == null) {
17609 stickyIntents = new ArrayList<Intent>();
17611 stickyIntents.addAll(intents);
17618 ArrayList<Intent> allSticky = null;
17619 if (stickyIntents != null) {
17620 final ContentResolver resolver = mContext.getContentResolver();
17621 // Look for any matching sticky broadcasts...
17622 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17623 Intent intent = stickyIntents.get(i);
17624 // If intent has scheme "content", it will need to acccess
17625 // provider that needs to lock mProviderMap in ActivityThread
17626 // and also it may need to wait application response, so we
17627 // cannot lock ActivityManagerService here.
17628 if (filter.match(resolver, intent, true, TAG) >= 0) {
17629 if (allSticky == null) {
17630 allSticky = new ArrayList<Intent>();
17632 allSticky.add(intent);
17637 // The first sticky in the list is returned directly back to the client.
17638 Intent sticky = allSticky != null ? allSticky.get(0) : null;
17639 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17640 if (receiver == null) {
17644 synchronized (this) {
17645 if (callerApp != null && (callerApp.thread == null
17646 || callerApp.thread.asBinder() != caller.asBinder())) {
17647 // Original caller already died
17650 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17652 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17654 if (rl.app != null) {
17655 rl.app.receivers.add(rl);
17658 receiver.asBinder().linkToDeath(rl, 0);
17659 } catch (RemoteException e) {
17662 rl.linkedToDeath = true;
17664 mRegisteredReceivers.put(receiver.asBinder(), rl);
17665 } else if (rl.uid != callingUid) {
17666 throw new IllegalArgumentException(
17667 "Receiver requested to register for uid " + callingUid
17668 + " was previously registered for uid " + rl.uid);
17669 } else if (rl.pid != callingPid) {
17670 throw new IllegalArgumentException(
17671 "Receiver requested to register for pid " + callingPid
17672 + " was previously registered for pid " + rl.pid);
17673 } else if (rl.userId != userId) {
17674 throw new IllegalArgumentException(
17675 "Receiver requested to register for user " + userId
17676 + " was previously registered for user " + rl.userId);
17678 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17679 permission, callingUid, userId);
17681 if (!bf.debugCheck()) {
17682 Slog.w(TAG, "==> For Dynamic broadcast");
17684 mReceiverResolver.addFilter(bf);
17686 // Enqueue broadcasts for all existing stickies that match
17688 if (allSticky != null) {
17689 ArrayList receivers = new ArrayList();
17692 final int stickyCount = allSticky.size();
17693 for (int i = 0; i < stickyCount; i++) {
17694 Intent intent = allSticky.get(i);
17695 BroadcastQueue queue = broadcastQueueForIntent(intent);
17696 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17697 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17698 null, 0, null, null, false, true, true, -1);
17699 queue.enqueueParallelBroadcastLocked(r);
17700 queue.scheduleBroadcastsLocked();
17708 public void unregisterReceiver(IIntentReceiver receiver) {
17709 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17711 final long origId = Binder.clearCallingIdentity();
17713 boolean doTrim = false;
17715 synchronized(this) {
17716 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17718 final BroadcastRecord r = rl.curBroadcast;
17719 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17720 final boolean doNext = r.queue.finishReceiverLocked(
17721 r, r.resultCode, r.resultData, r.resultExtras,
17722 r.resultAbort, false);
17725 r.queue.processNextBroadcast(false);
17729 if (rl.app != null) {
17730 rl.app.receivers.remove(rl);
17732 removeReceiverLocked(rl);
17733 if (rl.linkedToDeath) {
17734 rl.linkedToDeath = false;
17735 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17740 // If we actually concluded any broadcasts, we might now be able
17741 // to trim the recipients' apps from our working set
17743 trimApplications();
17748 Binder.restoreCallingIdentity(origId);
17752 void removeReceiverLocked(ReceiverList rl) {
17753 mRegisteredReceivers.remove(rl.receiver.asBinder());
17754 for (int i = rl.size() - 1; i >= 0; i--) {
17755 mReceiverResolver.removeFilter(rl.get(i));
17759 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17760 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17761 ProcessRecord r = mLruProcesses.get(i);
17762 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17764 r.thread.dispatchPackageBroadcast(cmd, packages);
17765 } catch (RemoteException ex) {
17771 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17772 int callingUid, int[] users) {
17773 // TODO: come back and remove this assumption to triage all broadcasts
17774 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17776 List<ResolveInfo> receivers = null;
17778 HashSet<ComponentName> singleUserReceivers = null;
17779 boolean scannedFirstReceivers = false;
17780 for (int user : users) {
17781 // Skip users that have Shell restrictions, with exception of always permitted
17782 // Shell broadcasts
17783 if (callingUid == Process.SHELL_UID
17784 && mUserController.hasUserRestriction(
17785 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17786 && !isPermittedShellBroadcast(intent)) {
17789 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17790 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17791 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17792 // If this is not the system user, we need to check for
17793 // any receivers that should be filtered out.
17794 for (int i=0; i<newReceivers.size(); i++) {
17795 ResolveInfo ri = newReceivers.get(i);
17796 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17797 newReceivers.remove(i);
17802 if (newReceivers != null && newReceivers.size() == 0) {
17803 newReceivers = null;
17805 if (receivers == null) {
17806 receivers = newReceivers;
17807 } else if (newReceivers != null) {
17808 // We need to concatenate the additional receivers
17809 // found with what we have do far. This would be easy,
17810 // but we also need to de-dup any receivers that are
17812 if (!scannedFirstReceivers) {
17813 // Collect any single user receivers we had already retrieved.
17814 scannedFirstReceivers = true;
17815 for (int i=0; i<receivers.size(); i++) {
17816 ResolveInfo ri = receivers.get(i);
17817 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17818 ComponentName cn = new ComponentName(
17819 ri.activityInfo.packageName, ri.activityInfo.name);
17820 if (singleUserReceivers == null) {
17821 singleUserReceivers = new HashSet<ComponentName>();
17823 singleUserReceivers.add(cn);
17827 // Add the new results to the existing results, tracking
17828 // and de-dupping single user receivers.
17829 for (int i=0; i<newReceivers.size(); i++) {
17830 ResolveInfo ri = newReceivers.get(i);
17831 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17832 ComponentName cn = new ComponentName(
17833 ri.activityInfo.packageName, ri.activityInfo.name);
17834 if (singleUserReceivers == null) {
17835 singleUserReceivers = new HashSet<ComponentName>();
17837 if (!singleUserReceivers.contains(cn)) {
17838 singleUserReceivers.add(cn);
17847 } catch (RemoteException ex) {
17848 // pm is in same process, this will never happen.
17853 private boolean isPermittedShellBroadcast(Intent intent) {
17854 // remote bugreport should always be allowed to be taken
17855 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17858 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17859 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17860 final String action = intent.getAction();
17861 if (isProtectedBroadcast
17862 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17863 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17864 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17865 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17866 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17867 || Intent.ACTION_MASTER_CLEAR.equals(action)
17868 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17869 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17870 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17871 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17872 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17873 // Broadcast is either protected, or it's a public action that
17874 // we've relaxed, so it's fine for system internals to send.
17878 // This broadcast may be a problem... but there are often system components that
17879 // want to send an internal broadcast to themselves, which is annoying to have to
17880 // explicitly list each action as a protected broadcast, so we will check for that
17881 // one safe case and allow it: an explicit broadcast, only being received by something
17882 // that has protected itself.
17883 if (receivers != null && receivers.size() > 0
17884 && (intent.getPackage() != null || intent.getComponent() != null)) {
17885 boolean allProtected = true;
17886 for (int i = receivers.size()-1; i >= 0; i--) {
17887 Object target = receivers.get(i);
17888 if (target instanceof ResolveInfo) {
17889 ResolveInfo ri = (ResolveInfo)target;
17890 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17891 allProtected = false;
17895 BroadcastFilter bf = (BroadcastFilter)target;
17896 if (bf.requiredPermission == null) {
17897 allProtected = false;
17902 if (allProtected) {
17908 // The vast majority of broadcasts sent from system internals
17909 // should be protected to avoid security holes, so yell loudly
17910 // to ensure we examine these cases.
17911 if (callerApp != null) {
17912 Log.wtf(TAG, "Sending non-protected broadcast " + action
17913 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17916 Log.wtf(TAG, "Sending non-protected broadcast " + action
17917 + " from system uid " + UserHandle.formatUid(callingUid)
17918 + " pkg " + callerPackage,
17923 final int broadcastIntentLocked(ProcessRecord callerApp,
17924 String callerPackage, Intent intent, String resolvedType,
17925 IIntentReceiver resultTo, int resultCode, String resultData,
17926 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17927 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17928 intent = new Intent(intent);
17930 // By default broadcasts do not go to stopped apps.
17931 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17933 // If we have not finished booting, don't allow this to launch new processes.
17934 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17935 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17938 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17939 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17940 + " ordered=" + ordered + " userid=" + userId);
17941 if ((resultTo != null) && !ordered) {
17942 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17945 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17946 ALLOW_NON_FULL, "broadcast", callerPackage);
17948 // Make sure that the user who is receiving this broadcast is running.
17949 // If not, we will just skip it. Make an exception for shutdown broadcasts
17950 // and upgrade steps.
17952 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17953 if ((callingUid != Process.SYSTEM_UID
17954 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17955 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17956 Slog.w(TAG, "Skipping broadcast of " + intent
17957 + ": user " + userId + " is stopped");
17958 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17962 BroadcastOptions brOptions = null;
17963 if (bOptions != null) {
17964 brOptions = new BroadcastOptions(bOptions);
17965 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17966 // See if the caller is allowed to do this. Note we are checking against
17967 // the actual real caller (not whoever provided the operation as say a
17968 // PendingIntent), because that who is actually supplied the arguments.
17969 if (checkComponentPermission(
17970 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17971 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17972 != PackageManager.PERMISSION_GRANTED) {
17973 String msg = "Permission Denial: " + intent.getAction()
17974 + " broadcast from " + callerPackage + " (pid=" + callingPid
17975 + ", uid=" + callingUid + ")"
17977 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17979 throw new SecurityException(msg);
17984 // Verify that protected broadcasts are only being sent by system code,
17985 // and that system code is only sending protected broadcasts.
17986 final String action = intent.getAction();
17987 final boolean isProtectedBroadcast;
17989 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17990 } catch (RemoteException e) {
17991 Slog.w(TAG, "Remote exception", e);
17992 return ActivityManager.BROADCAST_SUCCESS;
17995 final boolean isCallerSystem;
17996 switch (UserHandle.getAppId(callingUid)) {
17997 case Process.ROOT_UID:
17998 case Process.SYSTEM_UID:
17999 case Process.PHONE_UID:
18000 case Process.BLUETOOTH_UID:
18001 case Process.NFC_UID:
18002 isCallerSystem = true;
18005 isCallerSystem = (callerApp != null) && callerApp.persistent;
18009 // First line security check before anything else: stop non-system apps from
18010 // sending protected broadcasts.
18011 if (!isCallerSystem) {
18012 if (isProtectedBroadcast) {
18013 String msg = "Permission Denial: not allowed to send broadcast "
18014 + action + " from pid="
18015 + callingPid + ", uid=" + callingUid;
18017 throw new SecurityException(msg);
18019 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18020 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18021 // Special case for compatibility: we don't want apps to send this,
18022 // but historically it has not been protected and apps may be using it
18023 // to poke their own app widget. So, instead of making it protected,
18024 // just limit it to the caller.
18025 if (callerPackage == null) {
18026 String msg = "Permission Denial: not allowed to send broadcast "
18027 + action + " from unknown caller.";
18029 throw new SecurityException(msg);
18030 } else if (intent.getComponent() != null) {
18031 // They are good enough to send to an explicit component... verify
18032 // it is being sent to the calling app.
18033 if (!intent.getComponent().getPackageName().equals(
18035 String msg = "Permission Denial: not allowed to send broadcast "
18037 + intent.getComponent().getPackageName() + " from "
18040 throw new SecurityException(msg);
18043 // Limit broadcast to their own package.
18044 intent.setPackage(callerPackage);
18049 if (action != null) {
18051 case Intent.ACTION_UID_REMOVED:
18052 case Intent.ACTION_PACKAGE_REMOVED:
18053 case Intent.ACTION_PACKAGE_CHANGED:
18054 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18055 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18056 case Intent.ACTION_PACKAGES_SUSPENDED:
18057 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18058 // Handle special intents: if this broadcast is from the package
18059 // manager about a package being removed, we need to remove all of
18060 // its activities from the history stack.
18061 if (checkComponentPermission(
18062 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18063 callingPid, callingUid, -1, true)
18064 != PackageManager.PERMISSION_GRANTED) {
18065 String msg = "Permission Denial: " + intent.getAction()
18066 + " broadcast from " + callerPackage + " (pid=" + callingPid
18067 + ", uid=" + callingUid + ")"
18069 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18071 throw new SecurityException(msg);
18074 case Intent.ACTION_UID_REMOVED:
18075 final Bundle intentExtras = intent.getExtras();
18076 final int uid = intentExtras != null
18077 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18079 mBatteryStatsService.removeUid(uid);
18080 mAppOpsService.uidRemoved(uid);
18083 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18084 // If resources are unavailable just force stop all those packages
18085 // and flush the attribute cache as well.
18087 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18088 if (list != null && list.length > 0) {
18089 for (int i = 0; i < list.length; i++) {
18090 forceStopPackageLocked(list[i], -1, false, true, true,
18091 false, false, userId, "storage unmount");
18093 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18094 sendPackageBroadcastLocked(
18095 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18099 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18100 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18102 case Intent.ACTION_PACKAGE_REMOVED:
18103 case Intent.ACTION_PACKAGE_CHANGED:
18104 Uri data = intent.getData();
18106 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18107 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18108 final boolean replacing =
18109 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18110 final boolean killProcess =
18111 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18112 final boolean fullUninstall = removed && !replacing;
18115 forceStopPackageLocked(ssp, UserHandle.getAppId(
18116 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18117 false, true, true, false, fullUninstall, userId,
18118 removed ? "pkg removed" : "pkg changed");
18120 final int cmd = killProcess
18121 ? IApplicationThread.PACKAGE_REMOVED
18122 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18123 sendPackageBroadcastLocked(cmd,
18124 new String[] {ssp}, userId);
18125 if (fullUninstall) {
18126 mAppOpsService.packageRemoved(
18127 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18129 // Remove all permissions granted from/to this package
18130 removeUriPermissionsForPackageLocked(ssp, userId, true);
18132 removeTasksByPackageNameLocked(ssp, userId);
18134 // Hide the "unsupported display" dialog if necessary.
18135 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18136 mUnsupportedDisplaySizeDialog.getPackageName())) {
18137 mUnsupportedDisplaySizeDialog.dismiss();
18138 mUnsupportedDisplaySizeDialog = null;
18140 mCompatModePackages.handlePackageUninstalledLocked(ssp);
18141 mBatteryStatsService.notePackageUninstalled(ssp);
18145 killPackageProcessesLocked(ssp, UserHandle.getAppId(
18146 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18147 userId, ProcessList.INVALID_ADJ,
18148 false, true, true, false, "change " + ssp);
18150 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18151 intent.getStringArrayExtra(
18152 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18156 case Intent.ACTION_PACKAGES_SUSPENDED:
18157 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18158 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18159 intent.getAction());
18160 final String[] packageNames = intent.getStringArrayExtra(
18161 Intent.EXTRA_CHANGED_PACKAGE_LIST);
18162 final int userHandle = intent.getIntExtra(
18163 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18165 synchronized(ActivityManagerService.this) {
18166 mRecentTasks.onPackagesSuspendedChanged(
18167 packageNames, suspended, userHandle);
18172 case Intent.ACTION_PACKAGE_REPLACED:
18174 final Uri data = intent.getData();
18176 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18177 final ApplicationInfo aInfo =
18178 getPackageManagerInternalLocked().getApplicationInfo(
18181 if (aInfo == null) {
18182 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18183 + " ssp=" + ssp + " data=" + data);
18184 return ActivityManager.BROADCAST_SUCCESS;
18186 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18187 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18188 new String[] {ssp}, userId);
18192 case Intent.ACTION_PACKAGE_ADDED:
18194 // Special case for adding a package: by default turn on compatibility mode.
18195 Uri data = intent.getData();
18197 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18198 final boolean replacing =
18199 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18200 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18203 ApplicationInfo ai = AppGlobals.getPackageManager().
18204 getApplicationInfo(ssp, 0, 0);
18205 mBatteryStatsService.notePackageInstalled(ssp,
18206 ai != null ? ai.versionCode : 0);
18207 } catch (RemoteException e) {
18212 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18214 Uri data = intent.getData();
18216 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18217 // Hide the "unsupported display" dialog if necessary.
18218 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18219 mUnsupportedDisplaySizeDialog.getPackageName())) {
18220 mUnsupportedDisplaySizeDialog.dismiss();
18221 mUnsupportedDisplaySizeDialog = null;
18223 mCompatModePackages.handlePackageDataClearedLocked(ssp);
18227 case Intent.ACTION_TIMEZONE_CHANGED:
18228 // If this is the time zone changed action, queue up a message that will reset
18229 // the timezone of all currently running processes. This message will get
18230 // queued up before the broadcast happens.
18231 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18233 case Intent.ACTION_TIME_CHANGED:
18234 // If the user set the time, let all running processes know.
18235 final int is24Hour =
18236 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18238 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18239 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18240 synchronized (stats) {
18241 stats.noteCurrentTimeChangedLocked();
18244 case Intent.ACTION_CLEAR_DNS_CACHE:
18245 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18247 case Proxy.PROXY_CHANGE_ACTION:
18248 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18249 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18251 case android.hardware.Camera.ACTION_NEW_PICTURE:
18252 case android.hardware.Camera.ACTION_NEW_VIDEO:
18253 // These broadcasts are no longer allowed by the system, since they can
18254 // cause significant thrashing at a crictical point (using the camera).
18255 // Apps should use JobScehduler to monitor for media provider changes.
18256 Slog.w(TAG, action + " no longer allowed; dropping from "
18257 + UserHandle.formatUid(callingUid));
18258 if (resultTo != null) {
18259 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18261 queue.performReceiveLocked(callerApp, resultTo, intent,
18262 Activity.RESULT_CANCELED, null, null,
18263 false, false, userId);
18264 } catch (RemoteException e) {
18265 Slog.w(TAG, "Failure ["
18266 + queue.mQueueName + "] sending broadcast result of "
18271 // Lie; we don't want to crash the app.
18272 return ActivityManager.BROADCAST_SUCCESS;
18276 // Add to the sticky list if requested.
18278 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18279 callingPid, callingUid)
18280 != PackageManager.PERMISSION_GRANTED) {
18281 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18282 + callingPid + ", uid=" + callingUid
18283 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18285 throw new SecurityException(msg);
18287 if (requiredPermissions != null && requiredPermissions.length > 0) {
18288 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18289 + " and enforce permissions " + Arrays.toString(requiredPermissions));
18290 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18292 if (intent.getComponent() != null) {
18293 throw new SecurityException(
18294 "Sticky broadcasts can't target a specific component");
18296 // We use userId directly here, since the "all" target is maintained
18297 // as a separate set of sticky broadcasts.
18298 if (userId != UserHandle.USER_ALL) {
18299 // But first, if this is not a broadcast to all users, then
18300 // make sure it doesn't conflict with an existing broadcast to
18302 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18303 UserHandle.USER_ALL);
18304 if (stickies != null) {
18305 ArrayList<Intent> list = stickies.get(intent.getAction());
18306 if (list != null) {
18307 int N = list.size();
18309 for (i=0; i<N; i++) {
18310 if (intent.filterEquals(list.get(i))) {
18311 throw new IllegalArgumentException(
18312 "Sticky broadcast " + intent + " for user "
18313 + userId + " conflicts with existing global broadcast");
18319 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18320 if (stickies == null) {
18321 stickies = new ArrayMap<>();
18322 mStickyBroadcasts.put(userId, stickies);
18324 ArrayList<Intent> list = stickies.get(intent.getAction());
18325 if (list == null) {
18326 list = new ArrayList<>();
18327 stickies.put(intent.getAction(), list);
18329 final int stickiesCount = list.size();
18331 for (i = 0; i < stickiesCount; i++) {
18332 if (intent.filterEquals(list.get(i))) {
18333 // This sticky already exists, replace it.
18334 list.set(i, new Intent(intent));
18338 if (i >= stickiesCount) {
18339 list.add(new Intent(intent));
18344 if (userId == UserHandle.USER_ALL) {
18345 // Caller wants broadcast to go to all started users.
18346 users = mUserController.getStartedUserArrayLocked();
18348 // Caller wants broadcast to go to one specific user.
18349 users = new int[] {userId};
18352 // Figure out who all will receive this broadcast.
18353 List receivers = null;
18354 List<BroadcastFilter> registeredReceivers = null;
18355 // Need to resolve the intent to interested receivers...
18356 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18358 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18360 if (intent.getComponent() == null) {
18361 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18362 // Query one target user at a time, excluding shell-restricted users
18363 for (int i = 0; i < users.length; i++) {
18364 if (mUserController.hasUserRestriction(
18365 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18368 List<BroadcastFilter> registeredReceiversForUser =
18369 mReceiverResolver.queryIntent(intent,
18370 resolvedType, false, users[i]);
18371 if (registeredReceivers == null) {
18372 registeredReceivers = registeredReceiversForUser;
18373 } else if (registeredReceiversForUser != null) {
18374 registeredReceivers.addAll(registeredReceiversForUser);
18378 registeredReceivers = mReceiverResolver.queryIntent(intent,
18379 resolvedType, false, userId);
18383 final boolean replacePending =
18384 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18386 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18387 + " replacePending=" + replacePending);
18389 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18390 if (!ordered && NR > 0) {
18391 // If we are not serializing this broadcast, then send the
18392 // registered receivers separately so they don't wait for the
18393 // components to be launched.
18394 if (isCallerSystem) {
18395 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18396 isProtectedBroadcast, registeredReceivers);
18398 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18399 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18400 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18401 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18402 resultExtras, ordered, sticky, false, userId);
18403 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18404 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18406 queue.enqueueParallelBroadcastLocked(r);
18407 queue.scheduleBroadcastsLocked();
18409 registeredReceivers = null;
18413 // Merge into one list.
18415 if (receivers != null) {
18416 // A special case for PACKAGE_ADDED: do not allow the package
18417 // being added to see this broadcast. This prevents them from
18418 // using this as a back door to get run as soon as they are
18419 // installed. Maybe in the future we want to have a special install
18420 // broadcast or such for apps, but we'd like to deliberately make
18422 String skipPackages[] = null;
18423 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18424 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18425 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18426 Uri data = intent.getData();
18427 if (data != null) {
18428 String pkgName = data.getSchemeSpecificPart();
18429 if (pkgName != null) {
18430 skipPackages = new String[] { pkgName };
18433 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18434 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18436 if (skipPackages != null && (skipPackages.length > 0)) {
18437 for (String skipPackage : skipPackages) {
18438 if (skipPackage != null) {
18439 int NT = receivers.size();
18440 for (int it=0; it<NT; it++) {
18441 ResolveInfo curt = (ResolveInfo)receivers.get(it);
18442 if (curt.activityInfo.packageName.equals(skipPackage)) {
18443 receivers.remove(it);
18452 int NT = receivers != null ? receivers.size() : 0;
18454 ResolveInfo curt = null;
18455 BroadcastFilter curr = null;
18456 while (it < NT && ir < NR) {
18457 if (curt == null) {
18458 curt = (ResolveInfo)receivers.get(it);
18460 if (curr == null) {
18461 curr = registeredReceivers.get(ir);
18463 if (curr.getPriority() >= curt.priority) {
18464 // Insert this broadcast record into the final list.
18465 receivers.add(it, curr);
18471 // Skip to the next ResolveInfo in the final list.
18478 if (receivers == null) {
18479 receivers = new ArrayList();
18481 receivers.add(registeredReceivers.get(ir));
18485 if (isCallerSystem) {
18486 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18487 isProtectedBroadcast, receivers);
18490 if ((receivers != null && receivers.size() > 0)
18491 || resultTo != null) {
18492 BroadcastQueue queue = broadcastQueueForIntent(intent);
18493 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18494 callerPackage, callingPid, callingUid, resolvedType,
18495 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18496 resultData, resultExtras, ordered, sticky, false, userId);
18498 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18499 + ": prev had " + queue.mOrderedBroadcasts.size());
18500 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18501 "Enqueueing broadcast " + r.intent.getAction());
18503 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18505 queue.enqueueOrderedBroadcastLocked(r);
18506 queue.scheduleBroadcastsLocked();
18509 // There was nobody interested in the broadcast, but we still want to record
18510 // that it happened.
18511 if (intent.getComponent() == null && intent.getPackage() == null
18512 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18513 // This was an implicit broadcast... let's record it for posterity.
18514 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18518 return ActivityManager.BROADCAST_SUCCESS;
18521 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18522 int skipCount, long dispatchTime) {
18523 final long now = SystemClock.elapsedRealtime();
18524 if (mCurBroadcastStats == null ||
18525 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18526 mLastBroadcastStats = mCurBroadcastStats;
18527 if (mLastBroadcastStats != null) {
18528 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18529 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18531 mCurBroadcastStats = new BroadcastStats();
18533 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18536 final Intent verifyBroadcastLocked(Intent intent) {
18537 // Refuse possible leaked file descriptors
18538 if (intent != null && intent.hasFileDescriptors() == true) {
18539 throw new IllegalArgumentException("File descriptors passed in Intent");
18542 int flags = intent.getFlags();
18544 if (!mProcessesReady) {
18545 // if the caller really truly claims to know what they're doing, go
18546 // ahead and allow the broadcast without launching any receivers
18547 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18548 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18549 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18550 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18551 + " before boot completion");
18552 throw new IllegalStateException("Cannot broadcast before boot completed");
18556 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18557 throw new IllegalArgumentException(
18558 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18564 public final int broadcastIntent(IApplicationThread caller,
18565 Intent intent, String resolvedType, IIntentReceiver resultTo,
18566 int resultCode, String resultData, Bundle resultExtras,
18567 String[] requiredPermissions, int appOp, Bundle bOptions,
18568 boolean serialized, boolean sticky, int userId) {
18569 enforceNotIsolatedCaller("broadcastIntent");
18570 synchronized(this) {
18571 intent = verifyBroadcastLocked(intent);
18573 final ProcessRecord callerApp = getRecordForAppLocked(caller);
18574 final int callingPid = Binder.getCallingPid();
18575 final int callingUid = Binder.getCallingUid();
18576 final long origId = Binder.clearCallingIdentity();
18577 int res = broadcastIntentLocked(callerApp,
18578 callerApp != null ? callerApp.info.packageName : null,
18579 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18580 requiredPermissions, appOp, bOptions, serialized, sticky,
18581 callingPid, callingUid, userId);
18582 Binder.restoreCallingIdentity(origId);
18588 int broadcastIntentInPackage(String packageName, int uid,
18589 Intent intent, String resolvedType, IIntentReceiver resultTo,
18590 int resultCode, String resultData, Bundle resultExtras,
18591 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18593 synchronized(this) {
18594 intent = verifyBroadcastLocked(intent);
18596 final long origId = Binder.clearCallingIdentity();
18597 String[] requiredPermissions = requiredPermission == null ? null
18598 : new String[] {requiredPermission};
18599 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18600 resultTo, resultCode, resultData, resultExtras,
18601 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18602 sticky, -1, uid, userId);
18603 Binder.restoreCallingIdentity(origId);
18608 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18609 // Refuse possible leaked file descriptors
18610 if (intent != null && intent.hasFileDescriptors() == true) {
18611 throw new IllegalArgumentException("File descriptors passed in Intent");
18614 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18615 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18617 synchronized(this) {
18618 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18619 != PackageManager.PERMISSION_GRANTED) {
18620 String msg = "Permission Denial: unbroadcastIntent() from pid="
18621 + Binder.getCallingPid()
18622 + ", uid=" + Binder.getCallingUid()
18623 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18625 throw new SecurityException(msg);
18627 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18628 if (stickies != null) {
18629 ArrayList<Intent> list = stickies.get(intent.getAction());
18630 if (list != null) {
18631 int N = list.size();
18633 for (i=0; i<N; i++) {
18634 if (intent.filterEquals(list.get(i))) {
18639 if (list.size() <= 0) {
18640 stickies.remove(intent.getAction());
18643 if (stickies.size() <= 0) {
18644 mStickyBroadcasts.remove(userId);
18650 void backgroundServicesFinishedLocked(int userId) {
18651 for (BroadcastQueue queue : mBroadcastQueues) {
18652 queue.backgroundServicesFinishedLocked(userId);
18656 public void finishReceiver(IBinder who, int resultCode, String resultData,
18657 Bundle resultExtras, boolean resultAbort, int flags) {
18658 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18660 // Refuse possible leaked file descriptors
18661 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18662 throw new IllegalArgumentException("File descriptors passed in Bundle");
18665 final long origId = Binder.clearCallingIdentity();
18667 boolean doNext = false;
18670 synchronized(this) {
18671 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18672 ? mFgBroadcastQueue : mBgBroadcastQueue;
18673 r = queue.getMatchingOrderedReceiver(who);
18675 doNext = r.queue.finishReceiverLocked(r, resultCode,
18676 resultData, resultExtras, resultAbort, true);
18681 r.queue.processNextBroadcast(false);
18683 trimApplications();
18685 Binder.restoreCallingIdentity(origId);
18689 // =========================================================
18691 // =========================================================
18693 public boolean startInstrumentation(ComponentName className,
18694 String profileFile, int flags, Bundle arguments,
18695 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18696 int userId, String abiOverride) {
18697 enforceNotIsolatedCaller("startInstrumentation");
18698 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18699 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18700 // Refuse possible leaked file descriptors
18701 if (arguments != null && arguments.hasFileDescriptors()) {
18702 throw new IllegalArgumentException("File descriptors passed in Bundle");
18705 synchronized(this) {
18706 InstrumentationInfo ii = null;
18707 ApplicationInfo ai = null;
18709 ii = mContext.getPackageManager().getInstrumentationInfo(
18710 className, STOCK_PM_FLAGS);
18711 ai = AppGlobals.getPackageManager().getApplicationInfo(
18712 ii.targetPackage, STOCK_PM_FLAGS, userId);
18713 } catch (PackageManager.NameNotFoundException e) {
18714 } catch (RemoteException e) {
18717 reportStartInstrumentationFailureLocked(watcher, className,
18718 "Unable to find instrumentation info for: " + className);
18722 reportStartInstrumentationFailureLocked(watcher, className,
18723 "Unable to find instrumentation target package: " + ii.targetPackage);
18726 if (!ai.hasCode()) {
18727 reportStartInstrumentationFailureLocked(watcher, className,
18728 "Instrumentation target has no code: " + ii.targetPackage);
18732 int match = mContext.getPackageManager().checkSignatures(
18733 ii.targetPackage, ii.packageName);
18734 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18735 String msg = "Permission Denial: starting instrumentation "
18736 + className + " from pid="
18737 + Binder.getCallingPid()
18738 + ", uid=" + Binder.getCallingPid()
18739 + " not allowed because package " + ii.packageName
18740 + " does not have a signature matching the target "
18741 + ii.targetPackage;
18742 reportStartInstrumentationFailureLocked(watcher, className, msg);
18743 throw new SecurityException(msg);
18746 final long origId = Binder.clearCallingIdentity();
18747 // Instrumentation can kill and relaunch even persistent processes
18748 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18750 ProcessRecord app = addAppLocked(ai, false, abiOverride);
18751 app.instrumentationClass = className;
18752 app.instrumentationInfo = ai;
18753 app.instrumentationProfileFile = profileFile;
18754 app.instrumentationArguments = arguments;
18755 app.instrumentationWatcher = watcher;
18756 app.instrumentationUiAutomationConnection = uiAutomationConnection;
18757 app.instrumentationResultClass = className;
18758 Binder.restoreCallingIdentity(origId);
18765 * Report errors that occur while attempting to start Instrumentation. Always writes the
18766 * error to the logs, but if somebody is watching, send the report there too. This enables
18767 * the "am" command to report errors with more information.
18769 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
18770 * @param cn The component name of the instrumentation.
18771 * @param report The error report.
18773 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18774 ComponentName cn, String report) {
18775 Slog.w(TAG, report);
18776 if (watcher != null) {
18777 Bundle results = new Bundle();
18778 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18779 results.putString("Error", report);
18780 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18784 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18785 if (app.instrumentationWatcher != null) {
18786 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18787 app.instrumentationClass, resultCode, results);
18790 // Can't call out of the system process with a lock held, so post a message.
18791 if (app.instrumentationUiAutomationConnection != null) {
18792 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18793 app.instrumentationUiAutomationConnection).sendToTarget();
18796 app.instrumentationWatcher = null;
18797 app.instrumentationUiAutomationConnection = null;
18798 app.instrumentationClass = null;
18799 app.instrumentationInfo = null;
18800 app.instrumentationProfileFile = null;
18801 app.instrumentationArguments = null;
18803 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18807 public void finishInstrumentation(IApplicationThread target,
18808 int resultCode, Bundle results) {
18809 int userId = UserHandle.getCallingUserId();
18810 // Refuse possible leaked file descriptors
18811 if (results != null && results.hasFileDescriptors()) {
18812 throw new IllegalArgumentException("File descriptors passed in Intent");
18815 synchronized(this) {
18816 ProcessRecord app = getRecordForAppLocked(target);
18818 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18821 final long origId = Binder.clearCallingIdentity();
18822 finishInstrumentationLocked(app, resultCode, results);
18823 Binder.restoreCallingIdentity(origId);
18827 // =========================================================
18829 // =========================================================
18831 public ConfigurationInfo getDeviceConfigurationInfo() {
18832 ConfigurationInfo config = new ConfigurationInfo();
18833 synchronized (this) {
18834 config.reqTouchScreen = mConfiguration.touchscreen;
18835 config.reqKeyboardType = mConfiguration.keyboard;
18836 config.reqNavigation = mConfiguration.navigation;
18837 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18838 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18839 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18841 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18842 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18843 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18845 config.reqGlEsVersion = GL_ES_VERSION;
18850 ActivityStack getFocusedStack() {
18851 return mStackSupervisor.getFocusedStack();
18855 public int getFocusedStackId() throws RemoteException {
18856 ActivityStack focusedStack = getFocusedStack();
18857 if (focusedStack != null) {
18858 return focusedStack.getStackId();
18863 public Configuration getConfiguration() {
18865 synchronized(this) {
18866 ci = new Configuration(mConfiguration);
18867 ci.userSetLocale = false;
18873 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18874 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18875 synchronized (this) {
18876 mSuppressResizeConfigChanges = suppress;
18881 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18882 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18883 if (fromStackId == HOME_STACK_ID) {
18884 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18886 synchronized (this) {
18887 final long origId = Binder.clearCallingIdentity();
18889 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18891 Binder.restoreCallingIdentity(origId);
18897 public void updatePersistentConfiguration(Configuration values) {
18898 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18899 "updateConfiguration()");
18900 enforceWriteSettingsPermission("updateConfiguration()");
18901 if (values == null) {
18902 throw new NullPointerException("Configuration must not be null");
18905 int userId = UserHandle.getCallingUserId();
18907 synchronized(this) {
18908 updatePersistentConfigurationLocked(values, userId);
18912 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18913 final long origId = Binder.clearCallingIdentity();
18915 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18917 Binder.restoreCallingIdentity(origId);
18921 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18922 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18923 FONT_SCALE, 1.0f, userId);
18924 if (mConfiguration.fontScale != scaleFactor) {
18925 final Configuration configuration = mWindowManager.computeNewConfiguration();
18926 configuration.fontScale = scaleFactor;
18927 synchronized (this) {
18928 updatePersistentConfigurationLocked(configuration, userId);
18933 private void enforceWriteSettingsPermission(String func) {
18934 int uid = Binder.getCallingUid();
18935 if (uid == Process.ROOT_UID) {
18939 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18940 Settings.getPackageNameForUid(mContext, uid), false)) {
18944 String msg = "Permission Denial: " + func + " from pid="
18945 + Binder.getCallingPid()
18947 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18949 throw new SecurityException(msg);
18952 public void updateConfiguration(Configuration values) {
18953 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18954 "updateConfiguration()");
18956 synchronized(this) {
18957 if (values == null && mWindowManager != null) {
18958 // sentinel: fetch the current configuration from the window manager
18959 values = mWindowManager.computeNewConfiguration();
18962 if (mWindowManager != null) {
18963 mProcessList.applyDisplaySize(mWindowManager);
18966 final long origId = Binder.clearCallingIdentity();
18967 if (values != null) {
18968 Settings.System.clearConfiguration(values);
18970 updateConfigurationLocked(values, null, false);
18971 Binder.restoreCallingIdentity(origId);
18975 void updateUserConfigurationLocked() {
18976 Configuration configuration = new Configuration(mConfiguration);
18977 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18978 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18979 updateConfigurationLocked(configuration, null, false);
18982 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18983 boolean initLocale) {
18984 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18987 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18988 boolean initLocale, boolean deferResume) {
18989 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18990 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18991 UserHandle.USER_NULL, deferResume);
18994 // To cache the list of supported system locales
18995 private String[] mSupportedSystemLocales = null;
18998 * Do either or both things: (1) change the current configuration, and (2)
18999 * make sure the given activity is running with the (now) current
19000 * configuration. Returns true if the activity has been left running, or
19001 * false if <var>starting</var> is being destroyed to match the new
19004 * @param userId is only used when persistent parameter is set to true to persist configuration
19005 * for that particular user
19007 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19008 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19011 if (mWindowManager != null) {
19012 mWindowManager.deferSurfaceLayout();
19014 if (values != null) {
19015 Configuration newConfig = new Configuration(mConfiguration);
19016 changes = newConfig.updateFrom(values);
19017 if (changes != 0) {
19018 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19019 "Updating configuration to: " + values);
19021 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19023 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19024 final LocaleList locales = values.getLocales();
19025 int bestLocaleIndex = 0;
19026 if (locales.size() > 1) {
19027 if (mSupportedSystemLocales == null) {
19028 mSupportedSystemLocales =
19029 Resources.getSystem().getAssets().getLocales();
19031 bestLocaleIndex = Math.max(0,
19032 locales.getFirstMatchIndex(mSupportedSystemLocales));
19034 SystemProperties.set("persist.sys.locale",
19035 locales.get(bestLocaleIndex).toLanguageTag());
19036 LocaleList.setDefault(locales, bestLocaleIndex);
19037 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19038 locales.get(bestLocaleIndex)));
19041 mConfigurationSeq++;
19042 if (mConfigurationSeq <= 0) {
19043 mConfigurationSeq = 1;
19045 newConfig.seq = mConfigurationSeq;
19046 mConfiguration = newConfig;
19047 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19048 mUsageStatsService.reportConfigurationChange(newConfig,
19049 mUserController.getCurrentUserIdLocked());
19050 //mUsageStatsService.noteStartConfig(newConfig);
19052 final Configuration configCopy = new Configuration(mConfiguration);
19054 // TODO: If our config changes, should we auto dismiss any currently
19055 // showing dialogs?
19056 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19058 AttributeCache ac = AttributeCache.instance();
19060 ac.updateConfiguration(configCopy);
19063 // Make sure all resources in our process are updated
19064 // right now, so that anyone who is going to retrieve
19065 // resource values after we return will be sure to get
19066 // the new ones. This is especially important during
19067 // boot, where the first config change needs to guarantee
19068 // all resources have that config before following boot
19069 // code is executed.
19070 mSystemThread.applyConfigurationToResources(configCopy);
19072 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19073 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19074 msg.obj = new Configuration(configCopy);
19076 mHandler.sendMessage(msg);
19079 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19080 if (isDensityChange) {
19081 // Reset the unsupported display size dialog.
19082 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19084 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19085 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19088 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19089 ProcessRecord app = mLruProcesses.get(i);
19091 if (app.thread != null) {
19092 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19093 + app.processName + " new config " + mConfiguration);
19094 app.thread.scheduleConfigurationChanged(configCopy);
19096 } catch (Exception e) {
19099 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19100 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19101 | Intent.FLAG_RECEIVER_REPLACE_PENDING
19102 | Intent.FLAG_RECEIVER_FOREGROUND);
19103 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19104 null, AppOpsManager.OP_NONE, null, false, false,
19105 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19106 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19107 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19108 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19109 if (initLocale || !mProcessesReady) {
19110 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19112 broadcastIntentLocked(null, null, intent,
19113 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19114 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19117 // Update the configuration with WM first and check if any of the stacks need to be
19118 // resized due to the configuration change. If so, resize the stacks now and do any
19119 // relaunches if necessary. This way we don't need to relaunch again below in
19120 // ensureActivityConfigurationLocked().
19121 if (mWindowManager != null) {
19122 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19123 if (resizedStacks != null) {
19124 for (int stackId : resizedStacks) {
19125 final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19126 mStackSupervisor.resizeStackLocked(
19127 stackId, newBounds, null, null, false, false, deferResume);
19133 boolean kept = true;
19134 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19135 // mainStack is null during startup.
19136 if (mainStack != null) {
19137 if (changes != 0 && starting == null) {
19138 // If the configuration changed, and the caller is not already
19139 // in the process of starting an activity, then find the top
19140 // activity to check if its configuration needs to change.
19141 starting = mainStack.topRunningActivityLocked();
19144 if (starting != null) {
19145 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19146 // And we need to make sure at this point that all other activities
19147 // are made visible with the correct configuration.
19148 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19149 !PRESERVE_WINDOWS);
19152 if (mWindowManager != null) {
19153 mWindowManager.continueSurfaceLayout();
19159 * Decide based on the configuration whether we should shouw the ANR,
19160 * crash, etc dialogs. The idea is that if there is no affordence to
19161 * press the on-screen buttons, or the user experience would be more
19162 * greatly impacted than the crash itself, we shouldn't show the dialog.
19164 * A thought: SystemUI might also want to get told about this, the Power
19165 * dialog / global actions also might want different behaviors.
19167 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19168 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19169 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19170 && config.navigation == Configuration.NAVIGATION_NONAV);
19171 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19172 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19173 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19174 return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19178 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19179 synchronized (this) {
19180 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19181 if (srec != null) {
19182 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19188 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19189 Intent resultData) {
19191 synchronized (this) {
19192 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19194 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19200 public int getLaunchedFromUid(IBinder activityToken) {
19201 ActivityRecord srec;
19202 synchronized (this) {
19203 srec = ActivityRecord.forTokenLocked(activityToken);
19205 if (srec == null) {
19208 return srec.launchedFromUid;
19211 public String getLaunchedFromPackage(IBinder activityToken) {
19212 ActivityRecord srec;
19213 synchronized (this) {
19214 srec = ActivityRecord.forTokenLocked(activityToken);
19216 if (srec == null) {
19219 return srec.launchedFromPackage;
19222 // =========================================================
19223 // LIFETIME MANAGEMENT
19224 // =========================================================
19226 // Returns which broadcast queue the app is the current [or imminent] receiver
19227 // on, or 'null' if the app is not an active broadcast recipient.
19228 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19229 BroadcastRecord r = app.curReceiver;
19234 // It's not the current receiver, but it might be starting up to become one
19235 synchronized (this) {
19236 for (BroadcastQueue queue : mBroadcastQueues) {
19237 r = queue.mPendingBroadcast;
19238 if (r != null && r.curApp == app) {
19239 // found it; report which queue it's in
19248 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19249 int targetUid, ComponentName targetComponent, String targetProcess) {
19250 if (!mTrackingAssociations) {
19253 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19254 = mAssociations.get(targetUid);
19255 if (components == null) {
19256 components = new ArrayMap<>();
19257 mAssociations.put(targetUid, components);
19259 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19260 if (sourceUids == null) {
19261 sourceUids = new SparseArray<>();
19262 components.put(targetComponent, sourceUids);
19264 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19265 if (sourceProcesses == null) {
19266 sourceProcesses = new ArrayMap<>();
19267 sourceUids.put(sourceUid, sourceProcesses);
19269 Association ass = sourceProcesses.get(sourceProcess);
19271 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19273 sourceProcesses.put(sourceProcess, ass);
19277 if (ass.mNesting == 1) {
19278 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19279 ass.mLastState = sourceState;
19284 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19285 ComponentName targetComponent) {
19286 if (!mTrackingAssociations) {
19289 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19290 = mAssociations.get(targetUid);
19291 if (components == null) {
19294 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19295 if (sourceUids == null) {
19298 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19299 if (sourceProcesses == null) {
19302 Association ass = sourceProcesses.get(sourceProcess);
19303 if (ass == null || ass.mNesting <= 0) {
19307 if (ass.mNesting == 0) {
19308 long uptime = SystemClock.uptimeMillis();
19309 ass.mTime += uptime - ass.mStartTime;
19310 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19311 += uptime - ass.mLastStateUptime;
19312 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19316 private void noteUidProcessState(final int uid, final int state) {
19317 mBatteryStatsService.noteUidProcessState(uid, state);
19318 if (mTrackingAssociations) {
19319 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19320 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19321 = mAssociations.valueAt(i1);
19322 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19323 SparseArray<ArrayMap<String, Association>> sourceUids
19324 = targetComponents.valueAt(i2);
19325 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19326 if (sourceProcesses != null) {
19327 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19328 Association ass = sourceProcesses.valueAt(i4);
19329 if (ass.mNesting >= 1) {
19330 // currently associated
19331 long uptime = SystemClock.uptimeMillis();
19332 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19333 += uptime - ass.mLastStateUptime;
19334 ass.mLastState = state;
19335 ass.mLastStateUptime = uptime;
19344 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19345 boolean doingAll, long now) {
19346 if (mAdjSeq == app.adjSeq) {
19347 // This adjustment has already been computed.
19348 return app.curRawAdj;
19351 if (app.thread == null) {
19352 app.adjSeq = mAdjSeq;
19353 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19354 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19355 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19358 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19359 app.adjSource = null;
19360 app.adjTarget = null;
19362 app.cached = false;
19364 final int activitiesSize = app.activities.size();
19366 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19367 // The max adjustment doesn't allow this app to be anything
19368 // below foreground, so it is not worth doing work for it.
19369 app.adjType = "fixed";
19370 app.adjSeq = mAdjSeq;
19371 app.curRawAdj = app.maxAdj;
19372 app.foregroundActivities = false;
19373 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19374 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19375 // System processes can do UI, and when they do we want to have
19376 // them trim their memory after the user leaves the UI. To
19377 // facilitate this, here we need to determine whether or not it
19378 // is currently showing UI.
19379 app.systemNoUi = true;
19380 if (app == TOP_APP) {
19381 app.systemNoUi = false;
19382 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19383 app.adjType = "pers-top-activity";
19384 } else if (app.hasTopUi) {
19385 app.systemNoUi = false;
19386 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19387 app.adjType = "pers-top-ui";
19388 } else if (activitiesSize > 0) {
19389 for (int j = 0; j < activitiesSize; j++) {
19390 final ActivityRecord r = app.activities.get(j);
19392 app.systemNoUi = false;
19396 if (!app.systemNoUi) {
19397 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19399 return (app.curAdj=app.maxAdj);
19402 app.systemNoUi = false;
19404 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19406 // Determine the importance of the process, starting with most
19407 // important to least, and assign an appropriate OOM adjustment.
19411 boolean foregroundActivities = false;
19412 BroadcastQueue queue;
19413 if (app == TOP_APP) {
19414 // The last app on the list is the foreground app.
19415 adj = ProcessList.FOREGROUND_APP_ADJ;
19416 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19417 app.adjType = "top-activity";
19418 foregroundActivities = true;
19419 procState = PROCESS_STATE_CUR_TOP;
19420 } else if (app.instrumentationClass != null) {
19421 // Don't want to kill running instrumentation.
19422 adj = ProcessList.FOREGROUND_APP_ADJ;
19423 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19424 app.adjType = "instrumentation";
19425 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19426 } else if ((queue = isReceivingBroadcast(app)) != null) {
19427 // An app that is currently receiving a broadcast also
19428 // counts as being in the foreground for OOM killer purposes.
19429 // It's placed in a sched group based on the nature of the
19430 // broadcast as reflected by which queue it's active in.
19431 adj = ProcessList.FOREGROUND_APP_ADJ;
19432 schedGroup = (queue == mFgBroadcastQueue)
19433 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19434 app.adjType = "broadcast";
19435 procState = ActivityManager.PROCESS_STATE_RECEIVER;
19436 } else if (app.executingServices.size() > 0) {
19437 // An app that is currently executing a service callback also
19438 // counts as being in the foreground.
19439 adj = ProcessList.FOREGROUND_APP_ADJ;
19440 schedGroup = app.execServicesFg ?
19441 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19442 app.adjType = "exec-service";
19443 procState = ActivityManager.PROCESS_STATE_SERVICE;
19444 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19446 // As far as we know the process is empty. We may change our mind later.
19447 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19448 // At this point we don't actually know the adjustment. Use the cached adj
19449 // value that the caller wants us to.
19451 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19454 app.adjType = "cch-empty";
19457 // Examine all activities if not already foreground.
19458 if (!foregroundActivities && activitiesSize > 0) {
19459 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19460 for (int j = 0; j < activitiesSize; j++) {
19461 final ActivityRecord r = app.activities.get(j);
19462 if (r.app != app) {
19463 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19464 + " instead of expected " + app);
19465 if (r.app == null || (r.app.uid == app.uid)) {
19466 // Only fix things up when they look sane
19473 // App has a visible activity; only upgrade adjustment.
19474 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19475 adj = ProcessList.VISIBLE_APP_ADJ;
19476 app.adjType = "visible";
19478 if (procState > PROCESS_STATE_CUR_TOP) {
19479 procState = PROCESS_STATE_CUR_TOP;
19481 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19482 app.cached = false;
19484 foregroundActivities = true;
19485 if (r.task != null && minLayer > 0) {
19486 final int layer = r.task.mLayerRank;
19487 if (layer >= 0 && minLayer > layer) {
19492 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19493 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19494 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19495 app.adjType = "pausing";
19497 if (procState > PROCESS_STATE_CUR_TOP) {
19498 procState = PROCESS_STATE_CUR_TOP;
19500 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19501 app.cached = false;
19503 foregroundActivities = true;
19504 } else if (r.state == ActivityState.STOPPING) {
19505 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19506 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19507 app.adjType = "stopping";
19509 // For the process state, we will at this point consider the
19510 // process to be cached. It will be cached either as an activity
19511 // or empty depending on whether the activity is finishing. We do
19512 // this so that we can treat the process as cached for purposes of
19513 // memory trimming (determing current memory level, trim command to
19514 // send to process) since there can be an arbitrary number of stopping
19515 // processes and they should soon all go into the cached state.
19516 if (!r.finishing) {
19517 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19518 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19521 app.cached = false;
19523 foregroundActivities = true;
19525 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19526 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19527 app.adjType = "cch-act";
19531 if (adj == ProcessList.VISIBLE_APP_ADJ) {
19536 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19537 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19538 if (app.foregroundServices) {
19539 // The user is aware of this app, so make it visible.
19540 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19541 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19542 app.cached = false;
19543 app.adjType = "fg-service";
19544 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19545 } else if (app.forcingToForeground != null) {
19546 // The user is aware of this app, so make it visible.
19547 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19548 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19549 app.cached = false;
19550 app.adjType = "force-fg";
19551 app.adjSource = app.forcingToForeground;
19552 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19556 if (app == mHeavyWeightProcess) {
19557 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19558 // We don't want to kill the current heavy-weight process.
19559 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19560 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19561 app.cached = false;
19562 app.adjType = "heavy";
19564 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19565 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19569 if (app == mHomeProcess) {
19570 if (adj > ProcessList.HOME_APP_ADJ) {
19571 // This process is hosting what we currently consider to be the
19572 // home app, so we don't want to let it go into the background.
19573 adj = ProcessList.HOME_APP_ADJ;
19574 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19575 app.cached = false;
19576 app.adjType = "home";
19578 if (procState > ActivityManager.PROCESS_STATE_HOME) {
19579 procState = ActivityManager.PROCESS_STATE_HOME;
19583 if (app == mPreviousProcess && app.activities.size() > 0) {
19584 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19585 // This was the previous process that showed UI to the user.
19586 // We want to try to keep it around more aggressively, to give
19587 // a good experience around switching between two apps.
19588 adj = ProcessList.PREVIOUS_APP_ADJ;
19589 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19590 app.cached = false;
19591 app.adjType = "previous";
19593 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19594 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19598 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19599 + " reason=" + app.adjType);
19601 // By default, we use the computed adjustment. It may be changed if
19602 // there are applications dependent on our services or providers, but
19603 // this gives us a baseline and makes sure we don't get into an
19604 // infinite recursion.
19605 app.adjSeq = mAdjSeq;
19606 app.curRawAdj = adj;
19607 app.hasStartedServices = false;
19609 if (mBackupTarget != null && app == mBackupTarget.app) {
19610 // If possible we want to avoid killing apps while they're being backed up
19611 if (adj > ProcessList.BACKUP_APP_ADJ) {
19612 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19613 adj = ProcessList.BACKUP_APP_ADJ;
19614 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19615 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19617 app.adjType = "backup";
19618 app.cached = false;
19620 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19621 procState = ActivityManager.PROCESS_STATE_BACKUP;
19625 boolean mayBeTop = false;
19627 for (int is = app.services.size()-1;
19628 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19629 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19630 || procState > ActivityManager.PROCESS_STATE_TOP);
19632 ServiceRecord s = app.services.valueAt(is);
19633 if (s.startRequested) {
19634 app.hasStartedServices = true;
19635 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19636 procState = ActivityManager.PROCESS_STATE_SERVICE;
19638 if (app.hasShownUi && app != mHomeProcess) {
19639 // If this process has shown some UI, let it immediately
19640 // go to the LRU list because it may be pretty heavy with
19641 // UI stuff. We'll tag it with a label just to help
19642 // debug and understand what is going on.
19643 if (adj > ProcessList.SERVICE_ADJ) {
19644 app.adjType = "cch-started-ui-services";
19647 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19648 // This service has seen some activity within
19649 // recent memory, so we will keep its process ahead
19650 // of the background processes.
19651 if (adj > ProcessList.SERVICE_ADJ) {
19652 adj = ProcessList.SERVICE_ADJ;
19653 app.adjType = "started-services";
19654 app.cached = false;
19657 // If we have let the service slide into the background
19658 // state, still have some text describing what it is doing
19659 // even though the service no longer has an impact.
19660 if (adj > ProcessList.SERVICE_ADJ) {
19661 app.adjType = "cch-started-services";
19666 for (int conni = s.connections.size()-1;
19667 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19668 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19669 || procState > ActivityManager.PROCESS_STATE_TOP);
19671 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19673 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19674 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19675 || procState > ActivityManager.PROCESS_STATE_TOP);
19677 // XXX should compute this based on the max of
19678 // all connected clients.
19679 ConnectionRecord cr = clist.get(i);
19680 if (cr.binding.client == app) {
19681 // Binding to ourself is not interesting.
19685 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19686 ProcessRecord client = cr.binding.client;
19687 int clientAdj = computeOomAdjLocked(client, cachedAdj,
19688 TOP_APP, doingAll, now);
19689 int clientProcState = client.curProcState;
19690 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19691 // If the other app is cached for any reason, for purposes here
19692 // we are going to consider it empty. The specific cached state
19693 // doesn't propagate except under certain conditions.
19694 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19696 String adjType = null;
19697 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19698 // Not doing bind OOM management, so treat
19699 // this guy more like a started service.
19700 if (app.hasShownUi && app != mHomeProcess) {
19701 // If this process has shown some UI, let it immediately
19702 // go to the LRU list because it may be pretty heavy with
19703 // UI stuff. We'll tag it with a label just to help
19704 // debug and understand what is going on.
19705 if (adj > clientAdj) {
19706 adjType = "cch-bound-ui-services";
19708 app.cached = false;
19710 clientProcState = procState;
19712 if (now >= (s.lastActivity
19713 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19714 // This service has not seen activity within
19715 // recent memory, so allow it to drop to the
19716 // LRU list if there is no other reason to keep
19717 // it around. We'll also tag it with a label just
19718 // to help debug and undertand what is going on.
19719 if (adj > clientAdj) {
19720 adjType = "cch-bound-services";
19726 if (adj > clientAdj) {
19727 // If this process has recently shown UI, and
19728 // the process that is binding to it is less
19729 // important than being visible, then we don't
19730 // care about the binding as much as we care
19731 // about letting this process get into the LRU
19732 // list to be killed and restarted if needed for
19734 if (app.hasShownUi && app != mHomeProcess
19735 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19736 adjType = "cch-bound-ui-services";
19738 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19739 |Context.BIND_IMPORTANT)) != 0) {
19740 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19741 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19742 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19743 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19744 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19745 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19746 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19749 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19750 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19753 if (!client.cached) {
19754 app.cached = false;
19756 adjType = "service";
19759 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19760 // This will treat important bound services identically to
19761 // the top app, which may behave differently than generic
19762 // foreground work.
19763 if (client.curSchedGroup > schedGroup) {
19764 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19765 schedGroup = client.curSchedGroup;
19767 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19770 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19771 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19772 // Special handling of clients who are in the top state.
19773 // We *may* want to consider this process to be in the
19774 // top state as well, but only if there is not another
19775 // reason for it to be running. Being on the top is a
19776 // special state, meaning you are specifically running
19777 // for the current top app. If the process is already
19778 // running in the background for some other reason, it
19779 // is more important to continue considering it to be
19780 // in the background state.
19782 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19784 // Special handling for above-top states (persistent
19785 // processes). These should not bring the current process
19786 // into the top state, since they are not on top. Instead
19787 // give them the best state after that.
19788 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19790 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19791 } else if (mWakefulness
19792 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19793 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19796 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19799 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19804 if (clientProcState <
19805 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19807 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19810 if (procState > clientProcState) {
19811 procState = clientProcState;
19813 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19814 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19815 app.pendingUiClean = true;
19817 if (adjType != null) {
19818 app.adjType = adjType;
19819 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19820 .REASON_SERVICE_IN_USE;
19821 app.adjSource = cr.binding.client;
19822 app.adjSourceProcState = clientProcState;
19823 app.adjTarget = s.name;
19826 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19827 app.treatLikeActivity = true;
19829 final ActivityRecord a = cr.activity;
19830 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19831 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19832 (a.visible || a.state == ActivityState.RESUMED ||
19833 a.state == ActivityState.PAUSING)) {
19834 adj = ProcessList.FOREGROUND_APP_ADJ;
19835 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19836 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19837 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19839 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19842 app.cached = false;
19843 app.adjType = "service";
19844 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19845 .REASON_SERVICE_IN_USE;
19847 app.adjSourceProcState = procState;
19848 app.adjTarget = s.name;
19855 for (int provi = app.pubProviders.size()-1;
19856 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19857 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19858 || procState > ActivityManager.PROCESS_STATE_TOP);
19860 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19861 for (int i = cpr.connections.size()-1;
19862 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19863 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19864 || procState > ActivityManager.PROCESS_STATE_TOP);
19866 ContentProviderConnection conn = cpr.connections.get(i);
19867 ProcessRecord client = conn.client;
19868 if (client == app) {
19869 // Being our own client is not interesting.
19872 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19873 int clientProcState = client.curProcState;
19874 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19875 // If the other app is cached for any reason, for purposes here
19876 // we are going to consider it empty.
19877 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19879 if (adj > clientAdj) {
19880 if (app.hasShownUi && app != mHomeProcess
19881 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19882 app.adjType = "cch-ui-provider";
19884 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19885 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19886 app.adjType = "provider";
19888 app.cached &= client.cached;
19889 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19890 .REASON_PROVIDER_IN_USE;
19891 app.adjSource = client;
19892 app.adjSourceProcState = clientProcState;
19893 app.adjTarget = cpr.name;
19895 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19896 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19897 // Special handling of clients who are in the top state.
19898 // We *may* want to consider this process to be in the
19899 // top state as well, but only if there is not another
19900 // reason for it to be running. Being on the top is a
19901 // special state, meaning you are specifically running
19902 // for the current top app. If the process is already
19903 // running in the background for some other reason, it
19904 // is more important to continue considering it to be
19905 // in the background state.
19907 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19909 // Special handling for above-top states (persistent
19910 // processes). These should not bring the current process
19911 // into the top state, since they are not on top. Instead
19912 // give them the best state after that.
19914 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19917 if (procState > clientProcState) {
19918 procState = clientProcState;
19920 if (client.curSchedGroup > schedGroup) {
19921 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19924 // If the provider has external (non-framework) process
19925 // dependencies, ensure that its adjustment is at least
19926 // FOREGROUND_APP_ADJ.
19927 if (cpr.hasExternalProcessHandles()) {
19928 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19929 adj = ProcessList.FOREGROUND_APP_ADJ;
19930 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19931 app.cached = false;
19932 app.adjType = "provider";
19933 app.adjTarget = cpr.name;
19935 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19936 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19941 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19942 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19943 adj = ProcessList.PREVIOUS_APP_ADJ;
19944 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19945 app.cached = false;
19946 app.adjType = "provider";
19948 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19949 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19953 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19954 // A client of one of our services or providers is in the top state. We
19955 // *may* want to be in the top state, but not if we are already running in
19956 // the background for some other reason. For the decision here, we are going
19957 // to pick out a few specific states that we want to remain in when a client
19958 // is top (states that tend to be longer-term) and otherwise allow it to go
19959 // to the top state.
19960 switch (procState) {
19961 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19962 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19963 case ActivityManager.PROCESS_STATE_SERVICE:
19964 // These all are longer-term states, so pull them up to the top
19965 // of the background states, but not all the way to the top state.
19966 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19969 // Otherwise, top is a better choice, so take it.
19970 procState = ActivityManager.PROCESS_STATE_TOP;
19975 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19976 if (app.hasClientActivities) {
19977 // This is a cached process, but with client activities. Mark it so.
19978 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19979 app.adjType = "cch-client-act";
19980 } else if (app.treatLikeActivity) {
19981 // This is a cached process, but somebody wants us to treat it like it has
19982 // an activity, okay!
19983 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19984 app.adjType = "cch-as-act";
19988 if (adj == ProcessList.SERVICE_ADJ) {
19990 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19991 mNewNumServiceProcs++;
19992 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19993 if (!app.serviceb) {
19994 // This service isn't far enough down on the LRU list to
19995 // normally be a B service, but if we are low on RAM and it
19996 // is large we want to force it down since we would prefer to
19997 // keep launcher over it.
19998 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19999 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20000 app.serviceHighRam = true;
20001 app.serviceb = true;
20002 //Slog.i(TAG, "ADJ " + app + " high ram!");
20004 mNewNumAServiceProcs++;
20005 //Slog.i(TAG, "ADJ " + app + " not high ram!");
20008 app.serviceHighRam = false;
20011 if (app.serviceb) {
20012 adj = ProcessList.SERVICE_B_ADJ;
20016 app.curRawAdj = adj;
20018 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20019 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20020 if (adj > app.maxAdj) {
20022 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20023 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20027 // Do final modification to adj. Everything we do between here and applying
20028 // the final setAdj must be done in this function, because we will also use
20029 // it when computing the final cached adj later. Note that we don't need to
20030 // worry about this for max adj above, since max adj will always be used to
20031 // keep it out of the cached vaues.
20032 app.curAdj = app.modifyRawOomAdj(adj);
20033 app.curSchedGroup = schedGroup;
20034 app.curProcState = procState;
20035 app.foregroundActivities = foregroundActivities;
20037 return app.curRawAdj;
20041 * Record new PSS sample for a process.
20043 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20045 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20047 proc.lastPssTime = now;
20048 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20049 if (DEBUG_PSS) Slog.d(TAG_PSS,
20050 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20051 + " state=" + ProcessList.makeProcStateString(procState));
20052 if (proc.initialIdlePss == 0) {
20053 proc.initialIdlePss = pss;
20055 proc.lastPss = pss;
20056 proc.lastSwapPss = swapPss;
20057 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20058 proc.lastCachedPss = pss;
20059 proc.lastCachedSwapPss = swapPss;
20062 final SparseArray<Pair<Long, String>> watchUids
20063 = mMemWatchProcesses.getMap().get(proc.processName);
20065 if (watchUids != null) {
20066 Pair<Long, String> val = watchUids.get(proc.uid);
20068 val = watchUids.get(0);
20074 if (check != null) {
20075 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20076 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20077 if (!isDebuggable) {
20078 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20079 isDebuggable = true;
20082 if (isDebuggable) {
20083 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20084 final ProcessRecord myProc = proc;
20085 final File heapdumpFile = DumpHeapProvider.getJavaFile();
20086 mMemWatchDumpProcName = proc.processName;
20087 mMemWatchDumpFile = heapdumpFile.toString();
20088 mMemWatchDumpPid = proc.pid;
20089 mMemWatchDumpUid = proc.uid;
20090 BackgroundThread.getHandler().post(new Runnable() {
20092 public void run() {
20093 revokeUriPermission(ActivityThread.currentActivityThread()
20094 .getApplicationThread(),
20095 DumpHeapActivity.JAVA_URI,
20096 Intent.FLAG_GRANT_READ_URI_PERMISSION
20097 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20098 UserHandle.myUserId());
20099 ParcelFileDescriptor fd = null;
20101 heapdumpFile.delete();
20102 fd = ParcelFileDescriptor.open(heapdumpFile,
20103 ParcelFileDescriptor.MODE_CREATE |
20104 ParcelFileDescriptor.MODE_TRUNCATE |
20105 ParcelFileDescriptor.MODE_WRITE_ONLY |
20106 ParcelFileDescriptor.MODE_APPEND);
20107 IApplicationThread thread = myProc.thread;
20108 if (thread != null) {
20110 if (DEBUG_PSS) Slog.d(TAG_PSS,
20111 "Requesting dump heap from "
20112 + myProc + " to " + heapdumpFile);
20113 thread.dumpHeap(true, heapdumpFile.toString(), fd);
20114 } catch (RemoteException e) {
20117 } catch (FileNotFoundException e) {
20118 e.printStackTrace();
20123 } catch (IOException e) {
20130 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20131 + ", but debugging not enabled");
20138 * Schedule PSS collection of a process.
20140 void requestPssLocked(ProcessRecord proc, int procState) {
20141 if (mPendingPssProcesses.contains(proc)) {
20144 if (mPendingPssProcesses.size() == 0) {
20145 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20147 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20148 proc.pssProcState = procState;
20149 mPendingPssProcesses.add(proc);
20153 * Schedule PSS collection of all processes.
20155 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20157 if (now < (mLastFullPssTime +
20158 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20162 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
20163 mLastFullPssTime = now;
20164 mFullPssPending = true;
20165 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20166 mPendingPssProcesses.clear();
20167 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20168 ProcessRecord app = mLruProcesses.get(i);
20169 if (app.thread == null
20170 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20173 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20174 app.pssProcState = app.setProcState;
20175 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20176 mTestPssMode, isSleepingLocked(), now);
20177 mPendingPssProcesses.add(app);
20180 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20183 public void setTestPssMode(boolean enabled) {
20184 synchronized (this) {
20185 mTestPssMode = enabled;
20187 // Whenever we enable the mode, we want to take a snapshot all of current
20188 // process mem use.
20189 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20195 * Ask a given process to GC right now.
20197 final void performAppGcLocked(ProcessRecord app) {
20199 app.lastRequestedGc = SystemClock.uptimeMillis();
20200 if (app.thread != null) {
20201 if (app.reportLowMemory) {
20202 app.reportLowMemory = false;
20203 app.thread.scheduleLowMemory();
20205 app.thread.processInBackground();
20208 } catch (Exception e) {
20214 * Returns true if things are idle enough to perform GCs.
20216 private final boolean canGcNowLocked() {
20217 boolean processingBroadcasts = false;
20218 for (BroadcastQueue q : mBroadcastQueues) {
20219 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20220 processingBroadcasts = true;
20223 return !processingBroadcasts
20224 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20228 * Perform GCs on all processes that are waiting for it, but only
20229 * if things are idle.
20231 final void performAppGcsLocked() {
20232 final int N = mProcessesToGc.size();
20236 if (canGcNowLocked()) {
20237 while (mProcessesToGc.size() > 0) {
20238 ProcessRecord proc = mProcessesToGc.remove(0);
20239 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20240 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20241 <= SystemClock.uptimeMillis()) {
20242 // To avoid spamming the system, we will GC processes one
20243 // at a time, waiting a few seconds between each.
20244 performAppGcLocked(proc);
20245 scheduleAppGcsLocked();
20248 // It hasn't been long enough since we last GCed this
20249 // process... put it in the list to wait for its time.
20250 addProcessToGcListLocked(proc);
20256 scheduleAppGcsLocked();
20261 * If all looks good, perform GCs on all processes waiting for them.
20263 final void performAppGcsIfAppropriateLocked() {
20264 if (canGcNowLocked()) {
20265 performAppGcsLocked();
20268 // Still not idle, wait some more.
20269 scheduleAppGcsLocked();
20273 * Schedule the execution of all pending app GCs.
20275 final void scheduleAppGcsLocked() {
20276 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20278 if (mProcessesToGc.size() > 0) {
20279 // Schedule a GC for the time to the next process.
20280 ProcessRecord proc = mProcessesToGc.get(0);
20281 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20283 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20284 long now = SystemClock.uptimeMillis();
20285 if (when < (now+GC_TIMEOUT)) {
20286 when = now + GC_TIMEOUT;
20288 mHandler.sendMessageAtTime(msg, when);
20293 * Add a process to the array of processes waiting to be GCed. Keeps the
20294 * list in sorted order by the last GC time. The process can't already be
20297 final void addProcessToGcListLocked(ProcessRecord proc) {
20298 boolean added = false;
20299 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20300 if (mProcessesToGc.get(i).lastRequestedGc <
20301 proc.lastRequestedGc) {
20303 mProcessesToGc.add(i+1, proc);
20308 mProcessesToGc.add(0, proc);
20313 * Set up to ask a process to GC itself. This will either do it
20314 * immediately, or put it on the list of processes to gc the next
20315 * time things are idle.
20317 final void scheduleAppGcLocked(ProcessRecord app) {
20318 long now = SystemClock.uptimeMillis();
20319 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20322 if (!mProcessesToGc.contains(app)) {
20323 addProcessToGcListLocked(app);
20324 scheduleAppGcsLocked();
20328 final void checkExcessivePowerUsageLocked(boolean doKills) {
20329 updateCpuStatsNow();
20331 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20332 boolean doWakeKills = doKills;
20333 boolean doCpuKills = doKills;
20334 if (mLastPowerCheckRealtime == 0) {
20335 doWakeKills = false;
20337 if (mLastPowerCheckUptime == 0) {
20338 doCpuKills = false;
20340 if (stats.isScreenOn()) {
20341 doWakeKills = false;
20343 final long curRealtime = SystemClock.elapsedRealtime();
20344 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20345 final long curUptime = SystemClock.uptimeMillis();
20346 final long uptimeSince = curUptime - mLastPowerCheckUptime;
20347 mLastPowerCheckRealtime = curRealtime;
20348 mLastPowerCheckUptime = curUptime;
20349 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20350 doWakeKills = false;
20352 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20353 doCpuKills = false;
20355 int i = mLruProcesses.size();
20358 ProcessRecord app = mLruProcesses.get(i);
20359 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20361 synchronized (stats) {
20362 wtime = stats.getProcessWakeTime(app.info.uid,
20363 app.pid, curRealtime);
20365 long wtimeUsed = wtime - app.lastWakeTime;
20366 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20368 StringBuilder sb = new StringBuilder(128);
20369 sb.append("Wake for ");
20370 app.toShortString(sb);
20371 sb.append(": over ");
20372 TimeUtils.formatDuration(realtimeSince, sb);
20373 sb.append(" used ");
20374 TimeUtils.formatDuration(wtimeUsed, sb);
20376 sb.append((wtimeUsed*100)/realtimeSince);
20378 Slog.i(TAG_POWER, sb.toString());
20380 sb.append("CPU for ");
20381 app.toShortString(sb);
20382 sb.append(": over ");
20383 TimeUtils.formatDuration(uptimeSince, sb);
20384 sb.append(" used ");
20385 TimeUtils.formatDuration(cputimeUsed, sb);
20387 sb.append((cputimeUsed*100)/uptimeSince);
20389 Slog.i(TAG_POWER, sb.toString());
20391 // If a process has held a wake lock for more
20392 // than 50% of the time during this period,
20393 // that sounds bad. Kill!
20394 if (doWakeKills && realtimeSince > 0
20395 && ((wtimeUsed*100)/realtimeSince) >= 50) {
20396 synchronized (stats) {
20397 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20398 realtimeSince, wtimeUsed);
20400 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20401 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20402 } else if (doCpuKills && uptimeSince > 0
20403 && ((cputimeUsed*100)/uptimeSince) >= 25) {
20404 synchronized (stats) {
20405 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20406 uptimeSince, cputimeUsed);
20408 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20409 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20411 app.lastWakeTime = wtime;
20412 app.lastCpuTime = app.curCpuTime;
20418 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20420 boolean success = true;
20422 if (app.curRawAdj != app.setRawAdj) {
20423 app.setRawAdj = app.curRawAdj;
20428 if (app.curAdj != app.setAdj) {
20429 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20430 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20431 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20433 app.setAdj = app.curAdj;
20434 app.verifiedAdj = ProcessList.INVALID_ADJ;
20437 if (app.setSchedGroup != app.curSchedGroup) {
20438 int oldSchedGroup = app.setSchedGroup;
20439 app.setSchedGroup = app.curSchedGroup;
20440 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20441 "Setting sched group of " + app.processName
20442 + " to " + app.curSchedGroup);
20443 if (app.waitingToKill != null && app.curReceiver == null
20444 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20445 app.kill(app.waitingToKill, true);
20449 switch (app.curSchedGroup) {
20450 case ProcessList.SCHED_GROUP_BACKGROUND:
20451 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20453 case ProcessList.SCHED_GROUP_TOP_APP:
20454 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20455 processGroup = Process.THREAD_GROUP_TOP_APP;
20458 processGroup = Process.THREAD_GROUP_DEFAULT;
20461 long oldId = Binder.clearCallingIdentity();
20463 Process.setProcessGroup(app.pid, processGroup);
20464 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20465 // do nothing if we already switched to RT
20466 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20467 // Switch VR thread for app to SCHED_FIFO
20468 if (mInVrMode && app.vrThreadTid != 0) {
20470 Process.setThreadScheduler(app.vrThreadTid,
20471 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20472 } catch (IllegalArgumentException e) {
20473 // thread died, ignore
20476 if (mUseFifoUiScheduling) {
20477 // Switch UI pipeline for app to SCHED_FIFO
20478 app.savedPriority = Process.getThreadPriority(app.pid);
20480 Process.setThreadScheduler(app.pid,
20481 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20482 } catch (IllegalArgumentException e) {
20483 // thread died, ignore
20485 if (app.renderThreadTid != 0) {
20487 Process.setThreadScheduler(app.renderThreadTid,
20488 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20489 } catch (IllegalArgumentException e) {
20490 // thread died, ignore
20492 if (DEBUG_OOM_ADJ) {
20493 Slog.d("UI_FIFO", "Set RenderThread (TID " +
20494 app.renderThreadTid + ") to FIFO");
20497 if (DEBUG_OOM_ADJ) {
20498 Slog.d("UI_FIFO", "Not setting RenderThread TID");
20502 // Boost priority for top app UI and render threads
20503 Process.setThreadPriority(app.pid, -10);
20504 if (app.renderThreadTid != 0) {
20506 Process.setThreadPriority(app.renderThreadTid, -10);
20507 } catch (IllegalArgumentException e) {
20508 // thread died, ignore
20513 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20514 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20515 // Reset VR thread to SCHED_OTHER
20516 // Safe to do even if we're not in VR mode
20517 if (app.vrThreadTid != 0) {
20518 Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20520 if (mUseFifoUiScheduling) {
20521 // Reset UI pipeline to SCHED_OTHER
20522 Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20523 Process.setThreadPriority(app.pid, app.savedPriority);
20524 if (app.renderThreadTid != 0) {
20525 Process.setThreadScheduler(app.renderThreadTid,
20526 Process.SCHED_OTHER, 0);
20527 Process.setThreadPriority(app.renderThreadTid, -4);
20530 // Reset priority for top app UI and render threads
20531 Process.setThreadPriority(app.pid, 0);
20532 if (app.renderThreadTid != 0) {
20533 Process.setThreadPriority(app.renderThreadTid, 0);
20537 } catch (Exception e) {
20538 Slog.w(TAG, "Failed setting process group of " + app.pid
20539 + " to " + app.curSchedGroup);
20540 e.printStackTrace();
20542 Binder.restoreCallingIdentity(oldId);
20546 if (app.repForegroundActivities != app.foregroundActivities) {
20547 app.repForegroundActivities = app.foregroundActivities;
20548 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20550 if (app.repProcState != app.curProcState) {
20551 app.repProcState = app.curProcState;
20552 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20553 if (app.thread != null) {
20556 //RuntimeException h = new RuntimeException("here");
20557 Slog.i(TAG, "Sending new process state " + app.repProcState
20558 + " to " + app /*, h*/);
20560 app.thread.setProcessState(app.repProcState);
20561 } catch (RemoteException e) {
20565 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20566 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20567 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20568 // Experimental code to more aggressively collect pss while
20569 // running test... the problem is that this tends to collect
20570 // the data right when a process is transitioning between process
20571 // states, which well tend to give noisy data.
20572 long start = SystemClock.uptimeMillis();
20573 long pss = Debug.getPss(app.pid, mTmpLong, null);
20574 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20575 mPendingPssProcesses.remove(app);
20576 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20577 + " to " + app.curProcState + ": "
20578 + (SystemClock.uptimeMillis()-start) + "ms");
20580 app.lastStateTime = now;
20581 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20582 mTestPssMode, isSleepingLocked(), now);
20583 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20584 + ProcessList.makeProcStateString(app.setProcState) + " to "
20585 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20586 + (app.nextPssTime-now) + ": " + app);
20588 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20589 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20591 requestPssLocked(app, app.setProcState);
20592 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20593 mTestPssMode, isSleepingLocked(), now);
20594 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20595 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20597 if (app.setProcState != app.curProcState) {
20598 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20599 "Proc state change of " + app.processName
20600 + " to " + app.curProcState);
20601 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20602 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20603 if (setImportant && !curImportant) {
20604 // This app is no longer something we consider important enough to allow to
20605 // use arbitrary amounts of battery power. Note
20606 // its current wake lock time to later know to kill it if
20607 // it is not behaving well.
20608 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20609 synchronized (stats) {
20610 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20611 app.pid, nowElapsed);
20613 app.lastCpuTime = app.curCpuTime;
20616 // Inform UsageStats of important process state change
20617 // Must be called before updating setProcState
20618 maybeUpdateUsageStatsLocked(app, nowElapsed);
20620 app.setProcState = app.curProcState;
20621 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20622 app.notCachedSinceIdle = false;
20625 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20627 app.procStateChanged = true;
20629 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20630 > USAGE_STATS_INTERACTION_INTERVAL) {
20631 // For apps that sit around for a long time in the interactive state, we need
20632 // to report this at least once a day so they don't go idle.
20633 maybeUpdateUsageStatsLocked(app, nowElapsed);
20636 if (changes != 0) {
20637 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20638 "Changes in " + app + ": " + changes);
20639 int i = mPendingProcessChanges.size()-1;
20640 ProcessChangeItem item = null;
20642 item = mPendingProcessChanges.get(i);
20643 if (item.pid == app.pid) {
20644 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20645 "Re-using existing item: " + item);
20651 // No existing item in pending changes; need a new one.
20652 final int NA = mAvailProcessChanges.size();
20654 item = mAvailProcessChanges.remove(NA-1);
20655 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20656 "Retrieving available item: " + item);
20658 item = new ProcessChangeItem();
20659 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20660 "Allocating new item: " + item);
20663 item.pid = app.pid;
20664 item.uid = app.info.uid;
20665 if (mPendingProcessChanges.size() == 0) {
20666 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20667 "*** Enqueueing dispatch processes changed!");
20668 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20670 mPendingProcessChanges.add(item);
20672 item.changes |= changes;
20673 item.processState = app.repProcState;
20674 item.foregroundActivities = app.repForegroundActivities;
20675 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20676 "Item " + Integer.toHexString(System.identityHashCode(item))
20677 + " " + app.toShortString() + ": changes=" + item.changes
20678 + " procState=" + item.processState
20679 + " foreground=" + item.foregroundActivities
20680 + " type=" + app.adjType + " source=" + app.adjSource
20681 + " target=" + app.adjTarget);
20687 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20688 final UidRecord.ChangeItem pendingChange;
20689 if (uidRec == null || uidRec.pendingChange == null) {
20690 if (mPendingUidChanges.size() == 0) {
20691 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20692 "*** Enqueueing dispatch uid changed!");
20693 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20695 final int NA = mAvailUidChanges.size();
20697 pendingChange = mAvailUidChanges.remove(NA-1);
20698 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20699 "Retrieving available item: " + pendingChange);
20701 pendingChange = new UidRecord.ChangeItem();
20702 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20703 "Allocating new item: " + pendingChange);
20705 if (uidRec != null) {
20706 uidRec.pendingChange = pendingChange;
20707 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20708 // If this uid is going away, and we haven't yet reported it is gone,
20710 change = UidRecord.CHANGE_GONE_IDLE;
20712 } else if (uid < 0) {
20713 throw new IllegalArgumentException("No UidRecord or uid");
20715 pendingChange.uidRecord = uidRec;
20716 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20717 mPendingUidChanges.add(pendingChange);
20719 pendingChange = uidRec.pendingChange;
20720 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20721 change = UidRecord.CHANGE_GONE_IDLE;
20724 pendingChange.change = change;
20725 pendingChange.processState = uidRec != null
20726 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20729 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20730 String authority) {
20731 if (app == null) return;
20732 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20733 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20734 if (userState == null) return;
20735 final long now = SystemClock.elapsedRealtime();
20736 Long lastReported = userState.mProviderLastReportedFg.get(authority);
20737 if (lastReported == null || lastReported < now - 60 * 1000L) {
20738 if (mSystemReady) {
20739 // Cannot touch the user stats if not system ready
20740 mUsageStatsService.reportContentProviderUsage(
20741 authority, providerPkgName, app.userId);
20743 userState.mProviderLastReportedFg.put(authority, now);
20748 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20749 if (DEBUG_USAGE_STATS) {
20750 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20751 + "] state changes: old = " + app.setProcState + ", new = "
20752 + app.curProcState);
20754 if (mUsageStatsService == null) {
20757 boolean isInteraction;
20758 // To avoid some abuse patterns, we are going to be careful about what we consider
20759 // to be an app interaction. Being the top activity doesn't count while the display
20760 // is sleeping, nor do short foreground services.
20761 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20762 isInteraction = true;
20763 app.fgInteractionTime = 0;
20764 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20765 if (app.fgInteractionTime == 0) {
20766 app.fgInteractionTime = nowElapsed;
20767 isInteraction = false;
20769 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20772 // If the app was being forced to the foreground, by say a Toast, then
20773 // no need to treat it as an interaction
20774 isInteraction = app.forcingToForeground == null
20775 && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20776 app.fgInteractionTime = 0;
20778 if (isInteraction && (!app.reportedInteraction
20779 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20780 app.interactionEventTime = nowElapsed;
20781 String[] packages = app.getPackageList();
20782 if (packages != null) {
20783 for (int i = 0; i < packages.length; i++) {
20784 mUsageStatsService.reportEvent(packages[i], app.userId,
20785 UsageEvents.Event.SYSTEM_INTERACTION);
20789 app.reportedInteraction = isInteraction;
20790 if (!isInteraction) {
20791 app.interactionEventTime = 0;
20795 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20796 if (proc.thread != null) {
20797 if (proc.baseProcessTracker != null) {
20798 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20803 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20804 ProcessRecord TOP_APP, boolean doingAll, long now) {
20805 if (app.thread == null) {
20809 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20811 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20814 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20816 if (isForeground != proc.foregroundServices) {
20817 proc.foregroundServices = isForeground;
20818 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20820 if (isForeground) {
20821 if (curProcs == null) {
20822 curProcs = new ArrayList<ProcessRecord>();
20823 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20825 if (!curProcs.contains(proc)) {
20826 curProcs.add(proc);
20827 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20828 proc.info.packageName, proc.info.uid);
20831 if (curProcs != null) {
20832 if (curProcs.remove(proc)) {
20833 mBatteryStatsService.noteEvent(
20834 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20835 proc.info.packageName, proc.info.uid);
20836 if (curProcs.size() <= 0) {
20837 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20843 updateOomAdjLocked();
20848 private final ActivityRecord resumedAppLocked() {
20849 ActivityRecord act = mStackSupervisor.resumedAppLocked();
20853 pkg = act.packageName;
20854 uid = act.info.applicationInfo.uid;
20859 // Has the UID or resumed package name changed?
20860 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20861 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20862 if (mCurResumedPackage != null) {
20863 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20864 mCurResumedPackage, mCurResumedUid);
20866 mCurResumedPackage = pkg;
20867 mCurResumedUid = uid;
20868 if (mCurResumedPackage != null) {
20869 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20870 mCurResumedPackage, mCurResumedUid);
20876 final boolean updateOomAdjLocked(ProcessRecord app) {
20877 final ActivityRecord TOP_ACT = resumedAppLocked();
20878 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20879 final boolean wasCached = app.cached;
20883 // This is the desired cached adjusment we want to tell it to use.
20884 // If our app is currently cached, we know it, and that is it. Otherwise,
20885 // we don't know it yet, and it needs to now be cached we will then
20886 // need to do a complete oom adj.
20887 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20888 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20889 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20890 SystemClock.uptimeMillis());
20891 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20892 // Changed to/from cached state, so apps after it in the LRU
20893 // list may also be changed.
20894 updateOomAdjLocked();
20899 final void updateOomAdjLocked() {
20900 final ActivityRecord TOP_ACT = resumedAppLocked();
20901 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20902 final long now = SystemClock.uptimeMillis();
20903 final long nowElapsed = SystemClock.elapsedRealtime();
20904 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20905 final int N = mLruProcesses.size();
20908 RuntimeException e = new RuntimeException();
20909 e.fillInStackTrace();
20910 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20913 // Reset state in all uid records.
20914 for (int i=mActiveUids.size()-1; i>=0; i--) {
20915 final UidRecord uidRec = mActiveUids.valueAt(i);
20916 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20917 "Starting update of " + uidRec);
20921 mStackSupervisor.rankTaskLayersIfNeeded();
20924 mNewNumServiceProcs = 0;
20925 mNewNumAServiceProcs = 0;
20927 final int emptyProcessLimit;
20928 final int cachedProcessLimit;
20929 if (mProcessLimit <= 0) {
20930 emptyProcessLimit = cachedProcessLimit = 0;
20931 } else if (mProcessLimit == 1) {
20932 emptyProcessLimit = 1;
20933 cachedProcessLimit = 0;
20935 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20936 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20939 // Let's determine how many processes we have running vs.
20940 // how many slots we have for background processes; we may want
20941 // to put multiple processes in a slot of there are enough of
20943 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20944 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20945 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20946 if (numEmptyProcs > cachedProcessLimit) {
20947 // If there are more empty processes than our limit on cached
20948 // processes, then use the cached process limit for the factor.
20949 // This ensures that the really old empty processes get pushed
20950 // down to the bottom, so if we are running low on memory we will
20951 // have a better chance at keeping around more cached processes
20952 // instead of a gazillion empty processes.
20953 numEmptyProcs = cachedProcessLimit;
20955 int emptyFactor = numEmptyProcs/numSlots;
20956 if (emptyFactor < 1) emptyFactor = 1;
20957 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20958 if (cachedFactor < 1) cachedFactor = 1;
20959 int stepCached = 0;
20963 int numTrimming = 0;
20965 mNumNonCachedProcs = 0;
20966 mNumCachedHiddenProcs = 0;
20968 // First update the OOM adjustment for each of the
20969 // application processes based on their current state.
20970 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20971 int nextCachedAdj = curCachedAdj+1;
20972 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20973 int nextEmptyAdj = curEmptyAdj+2;
20974 for (int i=N-1; i>=0; i--) {
20975 ProcessRecord app = mLruProcesses.get(i);
20979 if (!app.killedByAm && app.thread != null) {
20980 app.procStateChanged = false;
20981 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20983 // If we haven't yet assigned the final cached adj
20984 // to the process, do that now.
20985 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20986 switch (app.curProcState) {
20987 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20988 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20989 // This process is a cached process holding activities...
20990 // assign it the next cached value for that type, and then
20991 // step that cached level.
20992 app.curRawAdj = curCachedAdj;
20993 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20994 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20995 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20997 if (curCachedAdj != nextCachedAdj) {
20999 if (stepCached >= cachedFactor) {
21001 curCachedAdj = nextCachedAdj;
21002 nextCachedAdj += 2;
21003 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21004 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21010 // For everything else, assign next empty cached process
21011 // level and bump that up. Note that this means that
21012 // long-running services that have dropped down to the
21013 // cached level will be treated as empty (since their process
21014 // state is still as a service), which is what we want.
21015 app.curRawAdj = curEmptyAdj;
21016 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21017 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21018 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21020 if (curEmptyAdj != nextEmptyAdj) {
21022 if (stepEmpty >= emptyFactor) {
21024 curEmptyAdj = nextEmptyAdj;
21026 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21027 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21035 applyOomAdjLocked(app, true, now, nowElapsed);
21037 // Count the number of process types.
21038 switch (app.curProcState) {
21039 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21040 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21041 mNumCachedHiddenProcs++;
21043 if (numCached > cachedProcessLimit) {
21044 app.kill("cached #" + numCached, true);
21047 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21048 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21049 && app.lastActivityTime < oldTime) {
21050 app.kill("empty for "
21051 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21052 / 1000) + "s", true);
21055 if (numEmpty > emptyProcessLimit) {
21056 app.kill("empty #" + numEmpty, true);
21061 mNumNonCachedProcs++;
21065 if (app.isolated && app.services.size() <= 0) {
21066 // If this is an isolated process, and there are no
21067 // services running in it, then the process is no longer
21068 // needed. We agressively kill these because we can by
21069 // definition not re-use the same process again, and it is
21070 // good to avoid having whatever code was running in them
21071 // left sitting around after no longer needed.
21072 app.kill("isolated not needed", true);
21074 // Keeping this process, update its uid.
21075 final UidRecord uidRec = app.uidRecord;
21076 if (uidRec != null && uidRec.curProcState > app.curProcState) {
21077 uidRec.curProcState = app.curProcState;
21081 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21082 && !app.killedByAm) {
21088 mNumServiceProcs = mNewNumServiceProcs;
21090 // Now determine the memory trimming level of background processes.
21091 // Unfortunately we need to start at the back of the list to do this
21092 // properly. We only do this if the number of background apps we
21093 // are managing to keep around is less than half the maximum we desire;
21094 // if we are keeping a good number around, we'll let them use whatever
21095 // memory they want.
21096 final int numCachedAndEmpty = numCached + numEmpty;
21098 if (numCached <= ProcessList.TRIM_CACHED_APPS
21099 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21100 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21101 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21102 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21103 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21105 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21108 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21110 // We always allow the memory level to go up (better). We only allow it to go
21111 // down if we are in a state where that is allowed, *and* the total number of processes
21112 // has gone down since last time.
21113 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21114 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21115 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21116 if (memFactor > mLastMemoryLevel) {
21117 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21118 memFactor = mLastMemoryLevel;
21119 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21122 if (memFactor != mLastMemoryLevel) {
21123 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21125 mLastMemoryLevel = memFactor;
21126 mLastNumProcesses = mLruProcesses.size();
21127 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21128 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21129 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21130 if (mLowRamStartTime == 0) {
21131 mLowRamStartTime = now;
21135 switch (memFactor) {
21136 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21137 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21139 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21140 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21143 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21146 int factor = numTrimming/3;
21148 if (mHomeProcess != null) minFactor++;
21149 if (mPreviousProcess != null) minFactor++;
21150 if (factor < minFactor) factor = minFactor;
21151 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21152 for (int i=N-1; i>=0; i--) {
21153 ProcessRecord app = mLruProcesses.get(i);
21157 if (allChanged || app.procStateChanged) {
21158 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21159 app.procStateChanged = false;
21161 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21162 && !app.killedByAm) {
21163 if (app.trimMemoryLevel < curLevel && app.thread != null) {
21165 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21166 "Trimming memory of " + app.processName + " to " + curLevel);
21167 app.thread.scheduleTrimMemory(curLevel);
21168 } catch (RemoteException e) {
21171 // For now we won't do this; our memory trimming seems
21172 // to be good enough at this point that destroying
21173 // activities causes more harm than good.
21174 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21175 && app != mHomeProcess && app != mPreviousProcess) {
21176 // Need to do this on its own message because the stack may not
21177 // be in a consistent state at this point.
21178 // For these apps we will also finish their activities
21179 // to help them free memory.
21180 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21184 app.trimMemoryLevel = curLevel;
21186 if (step >= factor) {
21188 switch (curLevel) {
21189 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21190 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21192 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21193 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21197 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21198 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21199 && app.thread != null) {
21201 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21202 "Trimming memory of heavy-weight " + app.processName
21203 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21204 app.thread.scheduleTrimMemory(
21205 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21206 } catch (RemoteException e) {
21209 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21211 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21212 || app.systemNoUi) && app.pendingUiClean) {
21213 // If this application is now in the background and it
21214 // had done UI, then give it the special trim level to
21215 // have it free UI resources.
21216 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21217 if (app.trimMemoryLevel < level && app.thread != null) {
21219 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21220 "Trimming memory of bg-ui " + app.processName
21222 app.thread.scheduleTrimMemory(level);
21223 } catch (RemoteException e) {
21226 app.pendingUiClean = false;
21228 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21230 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21231 "Trimming memory of fg " + app.processName
21232 + " to " + fgTrimLevel);
21233 app.thread.scheduleTrimMemory(fgTrimLevel);
21234 } catch (RemoteException e) {
21237 app.trimMemoryLevel = fgTrimLevel;
21241 if (mLowRamStartTime != 0) {
21242 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21243 mLowRamStartTime = 0;
21245 for (int i=N-1; i>=0; i--) {
21246 ProcessRecord app = mLruProcesses.get(i);
21247 if (allChanged || app.procStateChanged) {
21248 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21249 app.procStateChanged = false;
21251 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21252 || app.systemNoUi) && app.pendingUiClean) {
21253 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21254 && app.thread != null) {
21256 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21257 "Trimming memory of ui hidden " + app.processName
21258 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21259 app.thread.scheduleTrimMemory(
21260 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21261 } catch (RemoteException e) {
21264 app.pendingUiClean = false;
21266 app.trimMemoryLevel = 0;
21270 if (mAlwaysFinishActivities) {
21271 // Need to do this on its own message because the stack may not
21272 // be in a consistent state at this point.
21273 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21277 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21280 // Update from any uid changes.
21281 for (int i=mActiveUids.size()-1; i>=0; i--) {
21282 final UidRecord uidRec = mActiveUids.valueAt(i);
21283 int uidChange = UidRecord.CHANGE_PROCSTATE;
21284 if (uidRec.setProcState != uidRec.curProcState) {
21285 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21286 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21287 + " to " + uidRec.curProcState);
21288 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21289 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21290 uidRec.lastBackgroundTime = nowElapsed;
21291 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21292 // Note: the background settle time is in elapsed realtime, while
21293 // the handler time base is uptime. All this means is that we may
21294 // stop background uids later than we had intended, but that only
21295 // happens because the device was sleeping so we are okay anyway.
21296 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21301 uidChange = UidRecord.CHANGE_ACTIVE;
21302 uidRec.idle = false;
21304 uidRec.lastBackgroundTime = 0;
21306 uidRec.setProcState = uidRec.curProcState;
21307 enqueueUidChangeLocked(uidRec, -1, uidChange);
21308 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21312 if (mProcessStats.shouldWriteNowLocked(now)) {
21313 mHandler.post(new Runnable() {
21314 @Override public void run() {
21315 synchronized (ActivityManagerService.this) {
21316 mProcessStats.writeStateAsyncLocked();
21322 if (DEBUG_OOM_ADJ) {
21323 final long duration = SystemClock.uptimeMillis() - now;
21325 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21326 new RuntimeException("here").fillInStackTrace());
21328 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21333 final void idleUids() {
21334 synchronized (this) {
21335 final long nowElapsed = SystemClock.elapsedRealtime();
21336 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21338 for (int i=mActiveUids.size()-1; i>=0; i--) {
21339 final UidRecord uidRec = mActiveUids.valueAt(i);
21340 final long bgTime = uidRec.lastBackgroundTime;
21341 if (bgTime > 0 && !uidRec.idle) {
21342 if (bgTime <= maxBgTime) {
21343 uidRec.idle = true;
21344 doStopUidLocked(uidRec.uid, uidRec);
21346 if (nextTime == 0 || nextTime > bgTime) {
21352 if (nextTime > 0) {
21353 mHandler.removeMessages(IDLE_UIDS_MSG);
21354 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21355 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21360 final void runInBackgroundDisabled(int uid) {
21361 synchronized (this) {
21362 UidRecord uidRec = mActiveUids.get(uid);
21363 if (uidRec != null) {
21364 // This uid is actually running... should it be considered background now?
21366 doStopUidLocked(uidRec.uid, uidRec);
21369 // This uid isn't actually running... still send a report about it being "stopped".
21370 doStopUidLocked(uid, null);
21375 final void doStopUidLocked(int uid, final UidRecord uidRec) {
21376 mServices.stopInBackgroundLocked(uid);
21377 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21380 final void trimApplications() {
21381 synchronized (this) {
21384 // First remove any unused application processes whose package
21385 // has been removed.
21386 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21387 final ProcessRecord app = mRemovedProcesses.get(i);
21388 if (app.activities.size() == 0
21389 && app.curReceiver == null && app.services.size() == 0) {
21391 TAG, "Exiting empty application process "
21392 + app.toShortString() + " ("
21393 + (app.thread != null ? app.thread.asBinder() : null)
21395 if (app.pid > 0 && app.pid != MY_PID) {
21396 app.kill("empty", false);
21399 app.thread.scheduleExit();
21400 } catch (Exception e) {
21401 // Ignore exceptions.
21404 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21405 mRemovedProcesses.remove(i);
21407 if (app.persistent) {
21408 addAppLocked(app.info, false, null /* ABI override */);
21413 // Now update the oom adj for all processes.
21414 updateOomAdjLocked();
21418 /** This method sends the specified signal to each of the persistent apps */
21419 public void signalPersistentProcesses(int sig) throws RemoteException {
21420 if (sig != Process.SIGNAL_USR1) {
21421 throw new SecurityException("Only SIGNAL_USR1 is allowed");
21424 synchronized (this) {
21425 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21426 != PackageManager.PERMISSION_GRANTED) {
21427 throw new SecurityException("Requires permission "
21428 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21431 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21432 ProcessRecord r = mLruProcesses.get(i);
21433 if (r.thread != null && r.persistent) {
21434 Process.sendSignal(r.pid, sig);
21440 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21441 if (proc == null || proc == mProfileProc) {
21442 proc = mProfileProc;
21443 profileType = mProfileType;
21444 clearProfilerLocked();
21446 if (proc == null) {
21450 proc.thread.profilerControl(false, null, profileType);
21451 } catch (RemoteException e) {
21452 throw new IllegalStateException("Process disappeared");
21456 private void clearProfilerLocked() {
21457 if (mProfileFd != null) {
21459 mProfileFd.close();
21460 } catch (IOException e) {
21463 mProfileApp = null;
21464 mProfileProc = null;
21465 mProfileFile = null;
21467 mAutoStopProfiler = false;
21468 mSamplingInterval = 0;
21471 public boolean profileControl(String process, int userId, boolean start,
21472 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21475 synchronized (this) {
21476 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21477 // its own permission.
21478 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21479 != PackageManager.PERMISSION_GRANTED) {
21480 throw new SecurityException("Requires permission "
21481 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21484 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21485 throw new IllegalArgumentException("null profile info or fd");
21488 ProcessRecord proc = null;
21489 if (process != null) {
21490 proc = findProcessLocked(process, userId, "profileControl");
21493 if (start && (proc == null || proc.thread == null)) {
21494 throw new IllegalArgumentException("Unknown process: " + process);
21498 stopProfilerLocked(null, 0);
21499 setProfileApp(proc.info, proc.processName, profilerInfo);
21500 mProfileProc = proc;
21501 mProfileType = profileType;
21502 ParcelFileDescriptor fd = profilerInfo.profileFd;
21505 } catch (IOException e) {
21508 profilerInfo.profileFd = fd;
21509 proc.thread.profilerControl(start, profilerInfo, profileType);
21513 stopProfilerLocked(proc, profileType);
21514 if (profilerInfo != null && profilerInfo.profileFd != null) {
21516 profilerInfo.profileFd.close();
21517 } catch (IOException e) {
21524 } catch (RemoteException e) {
21525 throw new IllegalStateException("Process disappeared");
21527 if (profilerInfo != null && profilerInfo.profileFd != null) {
21529 profilerInfo.profileFd.close();
21530 } catch (IOException e) {
21536 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21537 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21538 userId, true, ALLOW_FULL_ONLY, callName, null);
21539 ProcessRecord proc = null;
21541 int pid = Integer.parseInt(process);
21542 synchronized (mPidsSelfLocked) {
21543 proc = mPidsSelfLocked.get(pid);
21545 } catch (NumberFormatException e) {
21548 if (proc == null) {
21549 ArrayMap<String, SparseArray<ProcessRecord>> all
21550 = mProcessNames.getMap();
21551 SparseArray<ProcessRecord> procs = all.get(process);
21552 if (procs != null && procs.size() > 0) {
21553 proc = procs.valueAt(0);
21554 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21555 for (int i=1; i<procs.size(); i++) {
21556 ProcessRecord thisProc = procs.valueAt(i);
21557 if (thisProc.userId == userId) {
21569 public boolean dumpHeap(String process, int userId, boolean managed,
21570 String path, ParcelFileDescriptor fd) throws RemoteException {
21573 synchronized (this) {
21574 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21575 // its own permission (same as profileControl).
21576 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21577 != PackageManager.PERMISSION_GRANTED) {
21578 throw new SecurityException("Requires permission "
21579 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21583 throw new IllegalArgumentException("null fd");
21586 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21587 if (proc == null || proc.thread == null) {
21588 throw new IllegalArgumentException("Unknown process: " + process);
21591 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21592 if (!isDebuggable) {
21593 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21594 throw new SecurityException("Process not debuggable: " + proc);
21598 proc.thread.dumpHeap(managed, path, fd);
21602 } catch (RemoteException e) {
21603 throw new IllegalStateException("Process disappeared");
21608 } catch (IOException e) {
21615 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21616 String reportPackage) {
21617 if (processName != null) {
21618 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21619 "setDumpHeapDebugLimit()");
21621 synchronized (mPidsSelfLocked) {
21622 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21623 if (proc == null) {
21624 throw new SecurityException("No process found for calling pid "
21625 + Binder.getCallingPid());
21627 if (!Build.IS_DEBUGGABLE
21628 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21629 throw new SecurityException("Not running a debuggable build");
21631 processName = proc.processName;
21633 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21634 throw new SecurityException("Package " + reportPackage + " is not running in "
21639 synchronized (this) {
21640 if (maxMemSize > 0) {
21641 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21644 mMemWatchProcesses.remove(processName, uid);
21646 mMemWatchProcesses.getMap().remove(processName);
21653 public void dumpHeapFinished(String path) {
21654 synchronized (this) {
21655 if (Binder.getCallingPid() != mMemWatchDumpPid) {
21656 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21657 + " does not match last pid " + mMemWatchDumpPid);
21660 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21661 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21662 + " does not match last path " + mMemWatchDumpFile);
21665 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21666 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21670 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21671 public void monitor() {
21672 synchronized (this) { }
21675 void onCoreSettingsChange(Bundle settings) {
21676 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21677 ProcessRecord processRecord = mLruProcesses.get(i);
21679 if (processRecord.thread != null) {
21680 processRecord.thread.setCoreSettings(settings);
21682 } catch (RemoteException re) {
21688 // Multi-user methods
21691 * Start user, if its not already running, but don't bring it to foreground.
21694 public boolean startUserInBackground(final int userId) {
21695 return mUserController.startUser(userId, /* foreground */ false);
21699 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21700 return mUserController.unlockUser(userId, token, secret, listener);
21704 public boolean switchUser(final int targetUserId) {
21705 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21706 UserInfo currentUserInfo;
21707 UserInfo targetUserInfo;
21708 synchronized (this) {
21709 int currentUserId = mUserController.getCurrentUserIdLocked();
21710 currentUserInfo = mUserController.getUserInfo(currentUserId);
21711 targetUserInfo = mUserController.getUserInfo(targetUserId);
21712 if (targetUserInfo == null) {
21713 Slog.w(TAG, "No user info for user #" + targetUserId);
21716 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21717 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21718 + " when device is in demo mode");
21721 if (!targetUserInfo.supportsSwitchTo()) {
21722 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21725 if (targetUserInfo.isManagedProfile()) {
21726 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21729 mUserController.setTargetUserIdLocked(targetUserId);
21731 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21732 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21733 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21737 void scheduleStartProfilesLocked() {
21738 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21739 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21740 DateUtils.SECOND_IN_MILLIS);
21745 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21746 return mUserController.stopUser(userId, force, callback);
21750 public UserInfo getCurrentUser() {
21751 return mUserController.getCurrentUser();
21755 public boolean isUserRunning(int userId, int flags) {
21756 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21757 && checkCallingPermission(INTERACT_ACROSS_USERS)
21758 != PackageManager.PERMISSION_GRANTED) {
21759 String msg = "Permission Denial: isUserRunning() from pid="
21760 + Binder.getCallingPid()
21761 + ", uid=" + Binder.getCallingUid()
21762 + " requires " + INTERACT_ACROSS_USERS;
21764 throw new SecurityException(msg);
21766 synchronized (this) {
21767 return mUserController.isUserRunningLocked(userId, flags);
21772 public int[] getRunningUserIds() {
21773 if (checkCallingPermission(INTERACT_ACROSS_USERS)
21774 != PackageManager.PERMISSION_GRANTED) {
21775 String msg = "Permission Denial: isUserRunning() from pid="
21776 + Binder.getCallingPid()
21777 + ", uid=" + Binder.getCallingUid()
21778 + " requires " + INTERACT_ACROSS_USERS;
21780 throw new SecurityException(msg);
21782 synchronized (this) {
21783 return mUserController.getStartedUserArrayLocked();
21788 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21789 mUserController.registerUserSwitchObserver(observer, name);
21793 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21794 mUserController.unregisterUserSwitchObserver(observer);
21797 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21798 if (info == null) return null;
21799 ApplicationInfo newInfo = new ApplicationInfo(info);
21800 newInfo.initForUser(userId);
21804 public boolean isUserStopped(int userId) {
21805 synchronized (this) {
21806 return mUserController.getStartedUserStateLocked(userId) == null;
21810 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21812 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21816 ActivityInfo info = new ActivityInfo(aInfo);
21817 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21821 private boolean processSanityChecksLocked(ProcessRecord process) {
21822 if (process == null || process.thread == null) {
21826 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21827 if (!isDebuggable) {
21828 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21836 public boolean startBinderTracking() throws RemoteException {
21837 synchronized (this) {
21838 mBinderTransactionTrackingEnabled = true;
21839 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21840 // permission (same as profileControl).
21841 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21842 != PackageManager.PERMISSION_GRANTED) {
21843 throw new SecurityException("Requires permission "
21844 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21847 for (int i = 0; i < mLruProcesses.size(); i++) {
21848 ProcessRecord process = mLruProcesses.get(i);
21849 if (!processSanityChecksLocked(process)) {
21853 process.thread.startBinderTracking();
21854 } catch (RemoteException e) {
21855 Log.v(TAG, "Process disappared");
21862 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21864 synchronized (this) {
21865 mBinderTransactionTrackingEnabled = false;
21866 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21867 // permission (same as profileControl).
21868 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21869 != PackageManager.PERMISSION_GRANTED) {
21870 throw new SecurityException("Requires permission "
21871 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21875 throw new IllegalArgumentException("null fd");
21878 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21879 pw.println("Binder transaction traces for all processes.\n");
21880 for (ProcessRecord process : mLruProcesses) {
21881 if (!processSanityChecksLocked(process)) {
21885 pw.println("Traces for process: " + process.processName);
21888 TransferPipe tp = new TransferPipe();
21890 process.thread.stopBinderTrackingAndDump(
21891 tp.getWriteFd().getFileDescriptor());
21892 tp.go(fd.getFileDescriptor());
21896 } catch (IOException e) {
21897 pw.println("Failure while dumping IPC traces from " + process +
21898 ". Exception: " + e);
21900 } catch (RemoteException e) {
21901 pw.println("Got a RemoteException while dumping IPC traces from " +
21902 process + ". Exception: " + e);
21913 } catch (IOException e) {
21919 private final class LocalService extends ActivityManagerInternal {
21921 public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
21922 int targetUserId) {
21923 synchronized (ActivityManagerService.this) {
21924 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
21925 targetPkg, intent, null, targetUserId);
21930 public String checkContentProviderAccess(String authority, int userId) {
21931 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21935 public void onWakefulnessChanged(int wakefulness) {
21936 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21940 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21941 String processName, String abiOverride, int uid, Runnable crashHandler) {
21942 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21943 processName, abiOverride, uid, crashHandler);
21947 public SleepToken acquireSleepToken(String tag) {
21948 Preconditions.checkNotNull(tag);
21950 ComponentName requestedVrService = null;
21951 ComponentName callingVrActivity = null;
21953 synchronized (ActivityManagerService.this) {
21954 if (mFocusedActivity != null) {
21955 requestedVrService = mFocusedActivity.requestedVrComponent;
21956 callingVrActivity = mFocusedActivity.info.getComponentName();
21957 userId = mFocusedActivity.userId;
21961 if (requestedVrService != null) {
21962 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21965 synchronized (ActivityManagerService.this) {
21966 SleepTokenImpl token = new SleepTokenImpl(tag);
21967 mSleepTokens.add(token);
21968 updateSleepIfNeededLocked();
21974 public ComponentName getHomeActivityForUser(int userId) {
21975 synchronized (ActivityManagerService.this) {
21976 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21977 return homeActivity == null ? null : homeActivity.realActivity;
21982 public void onUserRemoved(int userId) {
21983 synchronized (ActivityManagerService.this) {
21984 ActivityManagerService.this.onUserStoppedLocked(userId);
21989 public void onLocalVoiceInteractionStarted(IBinder activity,
21990 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21991 synchronized (ActivityManagerService.this) {
21992 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21993 voiceSession, voiceInteractor);
21998 public void notifyStartingWindowDrawn() {
21999 synchronized (ActivityManagerService.this) {
22000 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22005 public void notifyAppTransitionStarting(int reason) {
22006 synchronized (ActivityManagerService.this) {
22007 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22012 public void notifyAppTransitionFinished() {
22013 synchronized (ActivityManagerService.this) {
22014 mStackSupervisor.notifyAppTransitionDone();
22019 public void notifyAppTransitionCancelled() {
22020 synchronized (ActivityManagerService.this) {
22021 mStackSupervisor.notifyAppTransitionDone();
22026 public List<IBinder> getTopVisibleActivities() {
22027 synchronized (ActivityManagerService.this) {
22028 return mStackSupervisor.getTopVisibleActivities();
22033 public void notifyDockedStackMinimizedChanged(boolean minimized) {
22034 synchronized (ActivityManagerService.this) {
22035 mStackSupervisor.setDockedStackMinimized(minimized);
22040 public void killForegroundAppsForUser(int userHandle) {
22041 synchronized (ActivityManagerService.this) {
22042 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22043 final int NP = mProcessNames.getMap().size();
22044 for (int ip = 0; ip < NP; ip++) {
22045 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22046 final int NA = apps.size();
22047 for (int ia = 0; ia < NA; ia++) {
22048 final ProcessRecord app = apps.valueAt(ia);
22049 if (app.persistent) {
22050 // We don't kill persistent processes.
22055 } else if (app.userId == userHandle && app.foregroundActivities) {
22056 app.removed = true;
22062 final int N = procs.size();
22063 for (int i = 0; i < N; i++) {
22064 removeProcessLocked(procs.get(i), false, true, "kill all fg");
22070 public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22071 if (!(target instanceof PendingIntentRecord)) {
22072 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22075 ((PendingIntentRecord) target).setWhitelistDuration(duration);
22079 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22081 Preconditions.checkNotNull(values, "Configuration must not be null");
22082 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22083 synchronized (ActivityManagerService.this) {
22084 updateConfigurationLocked(values, null, false, true, userId,
22085 false /* deferResume */);
22090 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22092 Preconditions.checkNotNull(intents, "intents");
22093 final String[] resolvedTypes = new String[intents.length];
22094 for (int i = 0; i < intents.length; i++) {
22095 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22098 // UID of the package on user userId.
22099 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22100 // packageUid may not be initialized.
22101 int packageUid = 0;
22103 packageUid = AppGlobals.getPackageManager().getPackageUid(
22104 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22105 } catch (RemoteException e) {
22106 // Shouldn't happen.
22109 synchronized (ActivityManagerService.this) {
22110 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22111 /*resultTo*/ null, bOptions, userId);
22116 public int getUidProcessState(int uid) {
22117 return getUidState(uid);
22121 private final class SleepTokenImpl extends SleepToken {
22122 private final String mTag;
22123 private final long mAcquireTime;
22125 public SleepTokenImpl(String tag) {
22127 mAcquireTime = SystemClock.uptimeMillis();
22131 public void release() {
22132 synchronized (ActivityManagerService.this) {
22133 if (mSleepTokens.remove(this)) {
22134 updateSleepIfNeededLocked();
22140 public String toString() {
22141 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22146 * An implementation of IAppTask, that allows an app to manage its own tasks via
22147 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
22148 * only the process that calls getAppTasks() can call the AppTask methods.
22150 class AppTaskImpl extends IAppTask.Stub {
22151 private int mTaskId;
22152 private int mCallingUid;
22154 public AppTaskImpl(int taskId, int callingUid) {
22156 mCallingUid = callingUid;
22159 private void checkCaller() {
22160 if (mCallingUid != Binder.getCallingUid()) {
22161 throw new SecurityException("Caller " + mCallingUid
22162 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22167 public void finishAndRemoveTask() {
22170 synchronized (ActivityManagerService.this) {
22171 long origId = Binder.clearCallingIdentity();
22173 // We remove the task from recents to preserve backwards
22174 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22175 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22178 Binder.restoreCallingIdentity(origId);
22184 public ActivityManager.RecentTaskInfo getTaskInfo() {
22187 synchronized (ActivityManagerService.this) {
22188 long origId = Binder.clearCallingIdentity();
22190 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22192 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22194 return createRecentTaskInfoFromTaskRecord(tr);
22196 Binder.restoreCallingIdentity(origId);
22202 public void moveToFront() {
22204 // Will bring task to front if it already has a root activity.
22205 final long origId = Binder.clearCallingIdentity();
22207 synchronized (this) {
22208 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22211 Binder.restoreCallingIdentity(origId);
22216 public int startActivity(IBinder whoThread, String callingPackage,
22217 Intent intent, String resolvedType, Bundle bOptions) {
22220 int callingUser = UserHandle.getCallingUserId();
22222 IApplicationThread appThread;
22223 synchronized (ActivityManagerService.this) {
22224 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22226 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22228 appThread = ApplicationThreadNative.asInterface(whoThread);
22229 if (appThread == null) {
22230 throw new IllegalArgumentException("Bad app thread " + appThread);
22233 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22234 resolvedType, null, null, null, null, 0, 0, null, null,
22235 null, bOptions, false, callingUser, null, tr);
22239 public void setExcludeFromRecents(boolean exclude) {
22242 synchronized (ActivityManagerService.this) {
22243 long origId = Binder.clearCallingIdentity();
22245 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22247 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22249 Intent intent = tr.getBaseIntent();
22251 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22253 intent.setFlags(intent.getFlags()
22254 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22257 Binder.restoreCallingIdentity(origId);
22264 * Kill processes for the user with id userId and that depend on the package named packageName
22267 public void killPackageDependents(String packageName, int userId) {
22268 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22269 if (packageName == null) {
22270 throw new NullPointerException(
22271 "Cannot kill the dependents of a package without its name.");
22274 long callingId = Binder.clearCallingIdentity();
22275 IPackageManager pm = AppGlobals.getPackageManager();
22278 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22279 } catch (RemoteException e) {
22281 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22282 throw new IllegalArgumentException(
22283 "Cannot kill dependents of non-existing package " + packageName);
22286 synchronized(this) {
22287 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22288 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22289 "dep: " + packageName);
22292 Binder.restoreCallingIdentity(callingId);
22297 public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22298 final int userId = intent.getCreatorUserHandle().getIdentifier();
22299 if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22302 IIntentSender target = intent.getTarget();
22303 if (!(target instanceof PendingIntentRecord)) {
22306 final PendingIntentRecord record = (PendingIntentRecord) target;
22307 final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22308 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22309 // For direct boot aware activities, they can be shown without triggering a work challenge
22310 // before the profile user is unlocked.
22311 return rInfo != null && rInfo.activityInfo != null;