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.internal.util.ProgressReporter;
45 import com.android.server.AppOpsService;
46 import com.android.server.AttributeCache;
47 import com.android.server.DeviceIdleController;
48 import com.android.server.IntentResolver;
49 import com.android.server.LocalServices;
50 import com.android.server.LockGuard;
51 import com.android.server.ServiceThread;
52 import com.android.server.SystemService;
53 import com.android.server.SystemServiceManager;
54 import com.android.server.Watchdog;
55 import com.android.server.am.ActivityStack.ActivityState;
56 import com.android.server.firewall.IntentFirewall;
57 import com.android.server.pm.Installer;
58 import com.android.server.statusbar.StatusBarManagerInternal;
59 import com.android.server.vr.VrManagerInternal;
60 import com.android.server.wm.WindowManagerService;
62 import org.xmlpull.v1.XmlPullParser;
63 import org.xmlpull.v1.XmlPullParserException;
64 import org.xmlpull.v1.XmlSerializer;
66 import android.Manifest;
67 import android.annotation.UserIdInt;
68 import android.app.Activity;
69 import android.app.ActivityManager;
70 import android.app.ActivityManager.RunningTaskInfo;
71 import android.app.ActivityManager.StackId;
72 import android.app.ActivityManager.StackInfo;
73 import android.app.ActivityManager.TaskThumbnailInfo;
74 import android.app.ActivityManagerInternal;
75 import android.app.ActivityManagerInternal.SleepToken;
76 import android.app.ActivityManagerNative;
77 import android.app.ActivityOptions;
78 import android.app.ActivityThread;
79 import android.app.AlertDialog;
80 import android.app.AppGlobals;
81 import android.app.AppOpsManager;
82 import android.app.ApplicationErrorReport;
83 import android.app.ApplicationThreadNative;
84 import android.app.BroadcastOptions;
85 import android.app.Dialog;
86 import android.app.IActivityContainer;
87 import android.app.IActivityContainerCallback;
88 import android.app.IActivityController;
89 import android.app.IAppTask;
90 import android.app.IApplicationThread;
91 import android.app.IInstrumentationWatcher;
92 import android.app.INotificationManager;
93 import android.app.IProcessObserver;
94 import android.app.IServiceConnection;
95 import android.app.IStopUserCallback;
96 import android.app.ITaskStackListener;
97 import android.app.IUiAutomationConnection;
98 import android.app.IUidObserver;
99 import android.app.IUserSwitchObserver;
100 import android.app.Instrumentation;
101 import android.app.KeyguardManager;
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.admin.DevicePolicyManagerInternal;
108 import android.app.assist.AssistContent;
109 import android.app.assist.AssistStructure;
110 import android.app.backup.IBackupManager;
111 import android.app.usage.UsageEvents;
112 import android.app.usage.UsageStatsManagerInternal;
113 import android.appwidget.AppWidgetManager;
114 import android.content.ActivityNotFoundException;
115 import android.content.BroadcastReceiver;
116 import android.content.ClipData;
117 import android.content.ComponentCallbacks2;
118 import android.content.ComponentName;
119 import android.content.ContentProvider;
120 import android.content.ContentResolver;
121 import android.content.Context;
122 import android.content.DialogInterface;
123 import android.content.IContentProvider;
124 import android.content.IIntentReceiver;
125 import android.content.IIntentSender;
126 import android.content.Intent;
127 import android.content.IntentFilter;
128 import android.content.IntentSender;
129 import android.content.pm.ActivityInfo;
130 import android.content.pm.ApplicationInfo;
131 import android.content.pm.ConfigurationInfo;
132 import android.content.pm.IPackageDataObserver;
133 import android.content.pm.IPackageManager;
134 import android.content.pm.InstrumentationInfo;
135 import android.content.pm.PackageInfo;
136 import android.content.pm.PackageManager;
137 import android.content.pm.PackageManager.NameNotFoundException;
138 import android.content.pm.PackageManagerInternal;
139 import android.content.pm.ParceledListSlice;
140 import android.content.pm.PathPermission;
141 import android.content.pm.PermissionInfo;
142 import android.content.pm.ProviderInfo;
143 import android.content.pm.ResolveInfo;
144 import android.content.pm.ServiceInfo;
145 import android.content.pm.ShortcutServiceInternal;
146 import android.content.pm.UserInfo;
147 import android.content.res.CompatibilityInfo;
148 import android.content.res.Configuration;
149 import android.content.res.Resources;
150 import android.database.ContentObserver;
151 import android.graphics.Bitmap;
152 import android.graphics.Point;
153 import android.graphics.Rect;
154 import android.location.LocationManager;
155 import android.net.Proxy;
156 import android.net.ProxyInfo;
157 import android.net.Uri;
158 import android.os.BatteryStats;
159 import android.os.Binder;
160 import android.os.Build;
161 import android.os.Bundle;
162 import android.os.Debug;
163 import android.os.DropBoxManager;
164 import android.os.Environment;
165 import android.os.FactoryTest;
166 import android.os.FileObserver;
167 import android.os.FileUtils;
168 import android.os.Handler;
169 import android.os.IBinder;
170 import android.os.IPermissionController;
171 import android.os.IProcessInfoService;
172 import android.os.IProgressListener;
173 import android.os.LocaleList;
174 import android.os.Looper;
175 import android.os.Message;
176 import android.os.Parcel;
177 import android.os.ParcelFileDescriptor;
178 import android.os.PersistableBundle;
179 import android.os.PowerManager;
180 import android.os.PowerManagerInternal;
181 import android.os.Process;
182 import android.os.RemoteCallbackList;
183 import android.os.RemoteException;
184 import android.os.ResultReceiver;
185 import android.os.ServiceManager;
186 import android.os.StrictMode;
187 import android.os.SystemClock;
188 import android.os.SystemProperties;
189 import android.os.Trace;
190 import android.os.TransactionTooLargeException;
191 import android.os.UpdateLock;
192 import android.os.UserHandle;
193 import android.os.UserManager;
194 import android.os.WorkSource;
195 import android.os.storage.IMountService;
196 import android.os.storage.MountServiceInternal;
197 import android.os.storage.StorageManager;
198 import android.provider.Settings;
199 import android.service.voice.IVoiceInteractionSession;
200 import android.service.voice.VoiceInteractionManagerInternal;
201 import android.service.voice.VoiceInteractionSession;
202 import android.telecom.TelecomManager;
203 import android.text.format.DateUtils;
204 import android.text.format.Time;
205 import android.text.style.SuggestionSpan;
206 import android.util.ArrayMap;
207 import android.util.ArraySet;
208 import android.util.AtomicFile;
209 import android.util.DebugUtils;
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.FIRST_STATIC_STACK_ID;
263 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
265 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
266 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
267 import static android.app.ActivityManager.StackId.LAST_STATIC_STACK_ID;
268 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
269 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
270 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
271 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
272 import static android.content.pm.PackageManager.GET_PROVIDERS;
273 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
274 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
275 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
276 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
277 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
278 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
279 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
280 import static android.provider.Settings.Global.DEBUG_APP;
281 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
282 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
283 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
284 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
285 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
286 import static android.provider.Settings.System.FONT_SCALE;
287 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
288 import static com.android.internal.util.XmlUtils.readIntAttribute;
289 import static com.android.internal.util.XmlUtils.readLongAttribute;
290 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.writeIntAttribute;
292 import static com.android.internal.util.XmlUtils.writeLongAttribute;
293 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
294 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
326 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
327 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
350 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
351 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
352 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
353 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
354 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
355 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
356 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
357 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
358 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
359 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
360 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
361 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
362 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
363 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
364 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
365 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
366 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
368 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
369 import static org.xmlpull.v1.XmlPullParser.START_TAG;
371 public final class ActivityManagerService extends ActivityManagerNative
372 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
374 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
375 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
376 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
377 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
378 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
379 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
380 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
381 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
382 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
383 private static final String TAG_LRU = TAG + POSTFIX_LRU;
384 private static final String TAG_MU = TAG + POSTFIX_MU;
385 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
386 private static final String TAG_POWER = TAG + POSTFIX_POWER;
387 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
388 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
389 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
390 private static final String TAG_PSS = TAG + POSTFIX_PSS;
391 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
392 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
393 private static final String TAG_STACK = TAG + POSTFIX_STACK;
394 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
395 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
396 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
397 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
398 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
400 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
401 // here so that while the job scheduler can depend on AMS, the other way around
402 // need not be the case.
403 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
405 /** Control over CPU and battery monitoring */
406 // write battery stats every 30 minutes.
407 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
408 static final boolean MONITOR_CPU_USAGE = true;
409 // don't sample cpu less than every 5 seconds.
410 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
411 // wait possibly forever for next cpu sample.
412 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
413 static final boolean MONITOR_THREAD_CPU_USAGE = false;
415 // The flags that are set for all calls we make to the package manager.
416 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
418 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
420 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
422 // Amount of time after a call to stopAppSwitches() during which we will
423 // prevent further untrusted switches from happening.
424 static final long APP_SWITCH_DELAY_TIME = 5*1000;
426 // How long we wait for a launched process to attach to the activity manager
427 // before we decide it's never going to come up for real.
428 static final int PROC_START_TIMEOUT = 10*1000;
429 // How long we wait for an attached process to publish its content providers
430 // before we decide it must be hung.
431 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
433 // How long we will retain processes hosting content providers in the "last activity"
434 // state before allowing them to drop down to the regular cached LRU list. This is
435 // to avoid thrashing of provider processes under low memory situations.
436 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
438 // How long we wait for a launched process to attach to the activity manager
439 // before we decide it's never going to come up for real, when the process was
440 // started with a wrapper for instrumentation (such as Valgrind) because it
441 // could take much longer than usual.
442 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
444 // How long to wait after going idle before forcing apps to GC.
445 static final int GC_TIMEOUT = 5*1000;
447 // The minimum amount of time between successive GC requests for a process.
448 static final int GC_MIN_INTERVAL = 60*1000;
450 // The minimum amount of time between successive PSS requests for a process.
451 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
453 // The minimum amount of time between successive PSS requests for a process
454 // when the request is due to the memory state being lowered.
455 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
457 // The rate at which we check for apps using excessive power -- 15 mins.
458 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
460 // The minimum sample duration we will allow before deciding we have
461 // enough data on wake locks to start killing things.
462 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
464 // The minimum sample duration we will allow before deciding we have
465 // enough data on CPU usage to start killing things.
466 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
468 // How long we allow a receiver to run before giving up on it.
469 static final int BROADCAST_FG_TIMEOUT = 10*1000;
470 static final int BROADCAST_BG_TIMEOUT = 60*1000;
472 // How long we wait until we timeout on key dispatching.
473 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
475 // How long we wait until we timeout on key dispatching during instrumentation.
476 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
478 // This is the amount of time an app needs to be running a foreground service before
479 // we will consider it to be doing interaction for usage stats.
480 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
482 // Maximum amount of time we will allow to elapse before re-reporting usage stats
483 // interaction with foreground processes.
484 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
486 // This is the amount of time we allow an app to settle after it goes into the background,
487 // before we start restricting what it can do.
488 static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
490 // How long to wait in getAssistContextExtras for the activity and foreground services
491 // to respond with the result.
492 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
494 // How long top wait when going through the modern assist (which doesn't need to block
495 // on getting this result before starting to launch its UI).
496 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
498 // Maximum number of persisted Uri grants a package is allowed
499 static final int MAX_PERSISTED_URI_GRANTS = 128;
501 static final int MY_PID = Process.myPid();
503 static final String[] EMPTY_STRING_ARRAY = new String[0];
505 // How many bytes to write into the dropbox log before truncating
506 static final int DROPBOX_MAX_SIZE = 256 * 1024;
508 // Access modes for handleIncomingUser.
509 static final int ALLOW_NON_FULL = 0;
510 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
511 static final int ALLOW_FULL_ONLY = 2;
513 // Delay in notifying task stack change listeners (in millis)
514 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
516 // Necessary ApplicationInfo flags to mark an app as persistent
517 private static final int PERSISTENT_MASK =
518 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
520 // Intent sent when remote bugreport collection has been completed
521 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
522 "android.intent.action.REMOTE_BUGREPORT_FINISHED";
524 // Delay to disable app launch boost
525 static final int APP_BOOST_MESSAGE_DELAY = 3000;
526 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
527 static final int APP_BOOST_TIMEOUT = 2500;
529 // Used to indicate that a task is removed it should also be removed from recents.
530 private static final boolean REMOVE_FROM_RECENTS = true;
531 // Used to indicate that an app transition should be animated.
532 static final boolean ANIMATE = true;
534 // Determines whether to take full screen screenshots
535 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
536 public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
538 private static native int nativeMigrateToBoost();
539 private static native int nativeMigrateFromBoost();
540 private boolean mIsBoosted = false;
541 private long mBoostStartTime = 0;
543 /** All system services */
544 SystemServiceManager mSystemServiceManager;
546 private Installer mInstaller;
548 /** Run all ActivityStacks through this */
549 final ActivityStackSupervisor mStackSupervisor;
551 final ActivityStarter mActivityStarter;
553 /** Task stack change listeners. */
554 private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
555 new RemoteCallbackList<ITaskStackListener>();
557 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
559 public IntentFirewall mIntentFirewall;
561 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
562 // default actuion automatically. Important for devices without direct input
564 private boolean mShowDialogs = true;
565 private boolean mInVrMode = false;
567 BroadcastQueue mFgBroadcastQueue;
568 BroadcastQueue mBgBroadcastQueue;
569 // Convenient for easy iteration over the queues. Foreground is first
570 // so that dispatch of foreground broadcasts gets precedence.
571 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
573 BroadcastQueue broadcastQueueForIntent(Intent intent) {
574 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
575 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
576 "Broadcast intent " + intent + " on "
577 + (isFg ? "foreground" : "background") + " queue");
578 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
582 * Activity we have told the window manager to have key focus.
584 ActivityRecord mFocusedActivity = null;
587 * User id of the last activity mFocusedActivity was set to.
589 private int mLastFocusedUserId;
592 * If non-null, we are tracking the time the user spends in the currently focused app.
594 private AppTimeTracker mCurAppTimeTracker;
597 * List of intents that were used to start the most recent tasks.
599 final RecentTasks mRecentTasks;
602 * For addAppTask: cached of the last activity component that was added.
604 ComponentName mLastAddedTaskComponent;
607 * For addAppTask: cached of the last activity uid that was added.
609 int mLastAddedTaskUid;
612 * For addAppTask: cached of the last ActivityInfo that was added.
614 ActivityInfo mLastAddedTaskActivity;
617 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
619 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
622 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
624 String mDeviceOwnerName;
626 final UserController mUserController;
628 final AppErrors mAppErrors;
630 boolean mDoingSetFocusedActivity;
632 public boolean canShowErrorDialogs() {
633 return mShowDialogs && !mSleeping && !mShuttingDown;
636 // it's a semaphore; boost when 0->1, reset when 1->0
637 static ThreadLocal<Integer> sIsBoosted = new ThreadLocal<Integer>() {
638 @Override protected Integer initialValue() {
643 static void boostPriorityForLockedSection() {
644 if (sIsBoosted.get() == 0) {
645 // boost to prio 118 while holding a global lock
646 Process.setThreadPriority(Process.myTid(), -2);
647 //Log.e(TAG, "PRIORITY BOOST: set priority on TID " + Process.myTid());
649 int cur = sIsBoosted.get();
650 sIsBoosted.set(cur + 1);
653 static void resetPriorityAfterLockedSection() {
654 sIsBoosted.set(sIsBoosted.get() - 1);
655 if (sIsBoosted.get() == 0) {
656 //Log.e(TAG, "PRIORITY BOOST: reset priority on TID " + Process.myTid());
657 Process.setThreadPriority(Process.myTid(), 0);
660 public class PendingAssistExtras extends Binder implements Runnable {
661 public final ActivityRecord activity;
662 public final Bundle extras;
663 public final Intent intent;
664 public final String hint;
665 public final IResultReceiver receiver;
666 public final int userHandle;
667 public boolean haveResult = false;
668 public Bundle result = null;
669 public AssistStructure structure = null;
670 public AssistContent content = null;
671 public Bundle receiverExtras;
673 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
674 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
675 activity = _activity;
679 receiver = _receiver;
680 receiverExtras = _receiverExtras;
681 userHandle = _userHandle;
685 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
686 synchronized (this) {
690 pendingAssistExtrasTimedOut(this);
694 final ArrayList<PendingAssistExtras> mPendingAssistExtras
695 = new ArrayList<PendingAssistExtras>();
698 * Process management.
700 final ProcessList mProcessList = new ProcessList();
703 * All of the applications we currently have running organized by name.
704 * The keys are strings of the application package name (as
705 * returned by the package manager), and the keys are ApplicationRecord
708 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
711 * Tracking long-term execution of processes to look for abuse and other
714 final ProcessStatsService mProcessStats;
717 * The currently running isolated processes.
719 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
722 * Counter for assigning isolated process uids, to avoid frequently reusing the
725 int mNextIsolatedProcessUid = 0;
728 * The currently running heavy-weight process, if any.
730 ProcessRecord mHeavyWeightProcess = null;
733 * All of the processes we currently have running organized by pid.
734 * The keys are the pid running the application.
736 * <p>NOTE: This object is protected by its own lock, NOT the global
737 * activity manager lock!
739 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
742 * All of the processes that have been forced to be foreground. The key
743 * is the pid of the caller who requested it (we hold a death
746 abstract class ForegroundToken implements IBinder.DeathRecipient {
750 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
753 * List of records for processes that someone had tried to start before the
754 * system was ready. We don't start them at that point, but ensure they
755 * are started by the time booting is complete.
757 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
760 * List of persistent applications that are in the process
763 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
766 * Processes that are being forcibly torn down.
768 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
771 * List of running applications, sorted by recent usage.
772 * The first entry in the list is the least recently used.
774 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
777 * Where in mLruProcesses that the processes hosting activities start.
779 int mLruProcessActivityStart = 0;
782 * Where in mLruProcesses that the processes hosting services start.
783 * This is after (lower index) than mLruProcessesActivityStart.
785 int mLruProcessServiceStart = 0;
788 * List of processes that should gc as soon as things are idle.
790 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
793 * Processes we want to collect PSS data from.
795 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
797 private boolean mBinderTransactionTrackingEnabled = false;
800 * Last time we requested PSS data of all processes.
802 long mLastFullPssTime = SystemClock.uptimeMillis();
805 * If set, the next time we collect PSS data we should do a full collection
806 * with data from native processes and the kernel.
808 boolean mFullPssPending = false;
811 * This is the process holding what we currently consider to be
812 * the "home" activity.
814 ProcessRecord mHomeProcess;
817 * This is the process holding the activity the user last visited that
818 * is in a different process from the one they are currently in.
820 ProcessRecord mPreviousProcess;
823 * The time at which the previous process was last visible.
825 long mPreviousProcessVisibleTime;
828 * Track all uids that have actively running processes.
830 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
833 * This is for verifying the UID report flow.
835 static final boolean VALIDATE_UID_STATES = true;
836 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
839 * Packages that the user has asked to have run in screen size
840 * compatibility mode instead of filling the screen.
842 final CompatModePackages mCompatModePackages;
845 * Set of IntentSenderRecord objects that are currently active.
847 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
848 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
851 * Fingerprints (hashCode()) of stack traces that we've
852 * already logged DropBox entries for. Guarded by itself. If
853 * something (rogue user app) forces this over
854 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
856 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
857 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
860 * Strict Mode background batched logging state.
862 * The string buffer is guarded by itself, and its lock is also
863 * used to determine if another batched write is already
866 private final StringBuilder mStrictModeBuffer = new StringBuilder();
869 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
870 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
872 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
875 * Resolver for broadcast intents to registered receivers.
876 * Holds BroadcastFilter (subclass of IntentFilter).
878 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
879 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
881 protected boolean allowFilterResult(
882 BroadcastFilter filter, List<BroadcastFilter> dest) {
883 IBinder target = filter.receiverList.receiver.asBinder();
884 for (int i = dest.size() - 1; i >= 0; i--) {
885 if (dest.get(i).receiverList.receiver.asBinder() == target) {
893 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
894 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
895 || userId == filter.owningUserId) {
896 return super.newResult(filter, match, userId);
902 protected BroadcastFilter[] newArray(int size) {
903 return new BroadcastFilter[size];
907 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
908 return packageName.equals(filter.packageName);
913 * State of all active sticky broadcasts per user. Keys are the action of the
914 * sticky Intent, values are an ArrayList of all broadcasted intents with
915 * that action (which should usually be one). The SparseArray is keyed
916 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
917 * for stickies that are sent to all users.
919 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
920 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
922 final ActiveServices mServices;
924 final static class Association {
925 final int mSourceUid;
926 final String mSourceProcess;
927 final int mTargetUid;
928 final ComponentName mTargetComponent;
929 final String mTargetProcess;
937 // states of the source process when the bind occurred.
938 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
939 long mLastStateUptime;
940 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
941 - ActivityManager.MIN_PROCESS_STATE+1];
943 Association(int sourceUid, String sourceProcess, int targetUid,
944 ComponentName targetComponent, String targetProcess) {
945 mSourceUid = sourceUid;
946 mSourceProcess = sourceProcess;
947 mTargetUid = targetUid;
948 mTargetComponent = targetComponent;
949 mTargetProcess = targetProcess;
954 * When service association tracking is enabled, this is all of the associations we
955 * have seen. Mapping is target uid -> target component -> source uid -> source process name
956 * -> association data.
958 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
959 mAssociations = new SparseArray<>();
960 boolean mTrackingAssociations;
963 * Backup/restore process management
965 String mBackupAppName = null;
966 BackupRecord mBackupTarget = null;
968 final ProviderMap mProviderMap;
971 * List of content providers who have clients waiting for them. The
972 * application is currently being launched and the provider will be
973 * removed from this list once it is published.
975 final ArrayList<ContentProviderRecord> mLaunchingProviders
976 = new ArrayList<ContentProviderRecord>();
979 * File storing persisted {@link #mGrantedUriPermissions}.
981 private final AtomicFile mGrantFile;
983 /** XML constants used in {@link #mGrantFile} */
984 private static final String TAG_URI_GRANTS = "uri-grants";
985 private static final String TAG_URI_GRANT = "uri-grant";
986 private static final String ATTR_USER_HANDLE = "userHandle";
987 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
988 private static final String ATTR_TARGET_USER_ID = "targetUserId";
989 private static final String ATTR_SOURCE_PKG = "sourcePkg";
990 private static final String ATTR_TARGET_PKG = "targetPkg";
991 private static final String ATTR_URI = "uri";
992 private static final String ATTR_MODE_FLAGS = "modeFlags";
993 private static final String ATTR_CREATED_TIME = "createdTime";
994 private static final String ATTR_PREFIX = "prefix";
997 * Global set of specific {@link Uri} permissions that have been granted.
998 * This optimized lookup structure maps from {@link UriPermission#targetUid}
999 * to {@link UriPermission#uri} to {@link UriPermission}.
1002 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1003 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1005 public static class GrantUri {
1006 public final int sourceUserId;
1007 public final Uri uri;
1008 public boolean prefix;
1010 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1011 this.sourceUserId = sourceUserId;
1013 this.prefix = prefix;
1017 public int hashCode() {
1019 hashCode = 31 * hashCode + sourceUserId;
1020 hashCode = 31 * hashCode + uri.hashCode();
1021 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1026 public boolean equals(Object o) {
1027 if (o instanceof GrantUri) {
1028 GrantUri other = (GrantUri) o;
1029 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1030 && prefix == other.prefix;
1036 public String toString() {
1037 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1038 if (prefix) result += " [prefix]";
1042 public String toSafeString() {
1043 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1044 if (prefix) result += " [prefix]";
1048 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1049 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1050 ContentProvider.getUriWithoutUserId(uri), false);
1054 CoreSettingsObserver mCoreSettingsObserver;
1056 FontScaleSettingObserver mFontScaleSettingObserver;
1058 private final class FontScaleSettingObserver extends ContentObserver {
1059 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1061 public FontScaleSettingObserver() {
1063 ContentResolver resolver = mContext.getContentResolver();
1064 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1068 public void onChange(boolean selfChange, Uri uri) {
1069 if (mFontScaleUri.equals(uri)) {
1070 updateFontScaleIfNeeded();
1076 * Thread-local storage used to carry caller permissions over through
1077 * indirect content-provider access.
1079 private class Identity {
1080 public final IBinder token;
1081 public final int pid;
1082 public final int uid;
1084 Identity(IBinder _token, int _pid, int _uid) {
1091 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1094 * All information we have collected about the runtime performance of
1095 * any user id that can impact battery performance.
1097 final BatteryStatsService mBatteryStatsService;
1100 * Information about component usage
1102 UsageStatsManagerInternal mUsageStatsService;
1105 * Access to DeviceIdleController service.
1107 DeviceIdleController.LocalService mLocalDeviceIdleController;
1110 * Information about and control over application operations
1112 final AppOpsService mAppOpsService;
1115 * Current configuration information. HistoryRecord objects are given
1116 * a reference to this object to indicate which configuration they are
1117 * currently running in, so this object must be kept immutable.
1119 Configuration mConfiguration = new Configuration();
1122 * Current sequencing integer of the configuration, for skipping old
1125 int mConfigurationSeq = 0;
1127 boolean mSuppressResizeConfigChanges = false;
1130 * Hardware-reported OpenGLES version.
1132 final int GL_ES_VERSION;
1135 * List of initialization arguments to pass to all processes when binding applications to them.
1136 * For example, references to the commonly used services.
1138 HashMap<String, IBinder> mAppBindArgs;
1141 * Temporary to avoid allocations. Protected by main lock.
1143 final StringBuilder mStringBuilder = new StringBuilder(256);
1146 * Used to control how we initialize the service.
1148 ComponentName mTopComponent;
1149 String mTopAction = Intent.ACTION_MAIN;
1152 volatile boolean mProcessesReady = false;
1153 volatile boolean mSystemReady = false;
1154 volatile boolean mOnBattery = false;
1155 volatile int mFactoryTest;
1157 @GuardedBy("this") boolean mBooting = false;
1158 @GuardedBy("this") boolean mCallFinishBooting = false;
1159 @GuardedBy("this") boolean mBootAnimationComplete = false;
1160 @GuardedBy("this") boolean mLaunchWarningShown = false;
1161 @GuardedBy("this") boolean mCheckedForSetup = false;
1166 * The time at which we will allow normal application switches again,
1167 * after a call to {@link #stopAppSwitches()}.
1169 long mAppSwitchesAllowedTime;
1172 * This is set to true after the first switch after mAppSwitchesAllowedTime
1173 * is set; any switches after that will clear the time.
1175 boolean mDidAppSwitch;
1178 * Last time (in realtime) at which we checked for power usage.
1180 long mLastPowerCheckRealtime;
1183 * Last time (in uptime) at which we checked for power usage.
1185 long mLastPowerCheckUptime;
1188 * Set while we are wanting to sleep, to prevent any
1189 * activities from being started/resumed.
1191 private boolean mSleeping = false;
1194 * The process state used for processes that are running the top activities.
1195 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1197 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1200 * Set while we are running a voice interaction. This overrides
1201 * sleeping while it is active.
1203 private IVoiceInteractionSession mRunningVoice;
1206 * For some direct access we need to power manager.
1208 PowerManagerInternal mLocalPowerManager;
1211 * We want to hold a wake lock while running a voice interaction session, since
1212 * this may happen with the screen off and we need to keep the CPU running to
1213 * be able to continue to interact with the user.
1215 PowerManager.WakeLock mVoiceWakeLock;
1218 * State of external calls telling us if the device is awake or asleep.
1220 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1223 * A list of tokens that cause the top activity to be put to sleep.
1224 * They are used by components that may hide and block interaction with underlying
1227 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1229 static final int LOCK_SCREEN_HIDDEN = 0;
1230 static final int LOCK_SCREEN_LEAVING = 1;
1231 static final int LOCK_SCREEN_SHOWN = 2;
1233 * State of external call telling us if the lock screen is shown.
1235 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1238 * Set if we are shutting down the system, similar to sleeping.
1240 boolean mShuttingDown = false;
1243 * Current sequence id for oom_adj computation traversal.
1248 * Current sequence id for process LRU updating.
1253 * Keep track of the non-cached/empty process we last found, to help
1254 * determine how to distribute cached/empty processes next time.
1256 int mNumNonCachedProcs = 0;
1259 * Keep track of the number of cached hidden procs, to balance oom adj
1260 * distribution between those and empty procs.
1262 int mNumCachedHiddenProcs = 0;
1265 * Keep track of the number of service processes we last found, to
1266 * determine on the next iteration which should be B services.
1268 int mNumServiceProcs = 0;
1269 int mNewNumAServiceProcs = 0;
1270 int mNewNumServiceProcs = 0;
1273 * Allow the current computed overall memory level of the system to go down?
1274 * This is set to false when we are killing processes for reasons other than
1275 * memory management, so that the now smaller process list will not be taken as
1276 * an indication that memory is tighter.
1278 boolean mAllowLowerMemLevel = false;
1281 * The last computed memory level, for holding when we are in a state that
1282 * processes are going away for other reasons.
1284 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1287 * The last total number of process we have, to determine if changes actually look
1288 * like a shrinking number of process due to lower RAM.
1290 int mLastNumProcesses;
1293 * The uptime of the last time we performed idle maintenance.
1295 long mLastIdleTime = SystemClock.uptimeMillis();
1298 * Total time spent with RAM that has been added in the past since the last idle time.
1300 long mLowRamTimeSinceLastIdle = 0;
1303 * If RAM is currently low, when that horrible situation started.
1305 long mLowRamStartTime = 0;
1308 * For reporting to battery stats the current top application.
1310 private String mCurResumedPackage = null;
1311 private int mCurResumedUid = -1;
1314 * For reporting to battery stats the apps currently running foreground
1315 * service. The ProcessMap is package/uid tuples; each of these contain
1316 * an array of the currently foreground processes.
1318 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1319 = new ProcessMap<ArrayList<ProcessRecord>>();
1322 * This is set if we had to do a delayed dexopt of an app before launching
1323 * it, to increase the ANR timeouts in that case.
1328 * Set if the systemServer made a call to enterSafeMode.
1333 * If true, we are running under a test environment so will sample PSS from processes
1334 * much more rapidly to try to collect better data when the tests are rapidly
1335 * running through apps.
1337 boolean mTestPssMode = false;
1339 String mDebugApp = null;
1340 boolean mWaitForDebugger = false;
1341 boolean mDebugTransient = false;
1342 String mOrigDebugApp = null;
1343 boolean mOrigWaitForDebugger = false;
1344 boolean mAlwaysFinishActivities = false;
1345 boolean mLenientBackgroundCheck = false;
1346 boolean mForceResizableActivities;
1347 boolean mSupportsMultiWindow;
1348 boolean mSupportsFreeformWindowManagement;
1349 boolean mSupportsPictureInPicture;
1350 boolean mSupportsLeanbackOnly;
1351 Rect mDefaultPinnedStackBounds;
1352 IActivityController mController = null;
1353 boolean mControllerIsAMonkey = false;
1354 String mProfileApp = null;
1355 ProcessRecord mProfileProc = null;
1356 String mProfileFile;
1357 ParcelFileDescriptor mProfileFd;
1358 int mSamplingInterval = 0;
1359 boolean mAutoStopProfiler = false;
1360 int mProfileType = 0;
1361 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1362 String mMemWatchDumpProcName;
1363 String mMemWatchDumpFile;
1364 int mMemWatchDumpPid;
1365 int mMemWatchDumpUid;
1366 String mTrackAllocationApp = null;
1367 String mNativeDebuggingApp = null;
1369 final long[] mTmpLong = new long[2];
1371 static final class ProcessChangeItem {
1372 static final int CHANGE_ACTIVITIES = 1<<0;
1373 static final int CHANGE_PROCESS_STATE = 1<<1;
1378 boolean foregroundActivities;
1381 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1382 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1384 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1385 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1387 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1388 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1390 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1391 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1394 * Runtime CPU use collection thread. This object's lock is used to
1395 * perform synchronization with the thread (notifying it to run).
1397 final Thread mProcessCpuThread;
1400 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1401 * Must acquire this object's lock when accessing it.
1402 * NOTE: this lock will be held while doing long operations (trawling
1403 * through all processes in /proc), so it should never be acquired by
1404 * any critical paths such as when holding the main activity manager lock.
1406 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1407 MONITOR_THREAD_CPU_USAGE);
1408 final AtomicLong mLastCpuTime = new AtomicLong(0);
1409 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1411 long mLastWriteTime = 0;
1414 * Used to retain an update lock when the foreground activity is in
1417 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1420 * Set to true after the system has finished booting.
1422 boolean mBooted = false;
1424 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1425 int mProcessLimitOverride = -1;
1427 WindowManagerService mWindowManager;
1428 final ActivityThread mSystemThread;
1430 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1431 final ProcessRecord mApp;
1433 final IApplicationThread mAppThread;
1435 AppDeathRecipient(ProcessRecord app, int pid,
1436 IApplicationThread thread) {
1437 if (DEBUG_ALL) Slog.v(
1438 TAG, "New death recipient " + this
1439 + " for thread " + thread.asBinder());
1442 mAppThread = thread;
1446 public void binderDied() {
1447 if (DEBUG_ALL) Slog.v(
1448 TAG, "Death received in " + this
1449 + " for thread " + mAppThread.asBinder());
1450 synchronized(ActivityManagerService.this) {
1451 appDiedLocked(mApp, mPid, mAppThread, true);
1456 static final int SHOW_ERROR_UI_MSG = 1;
1457 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1458 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1459 static final int UPDATE_CONFIGURATION_MSG = 4;
1460 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1461 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1462 static final int SERVICE_TIMEOUT_MSG = 12;
1463 static final int UPDATE_TIME_ZONE = 13;
1464 static final int SHOW_UID_ERROR_UI_MSG = 14;
1465 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1466 static final int PROC_START_TIMEOUT_MSG = 20;
1467 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1468 static final int KILL_APPLICATION_MSG = 22;
1469 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1470 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1471 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1472 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1473 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1474 static final int CLEAR_DNS_CACHE_MSG = 28;
1475 static final int UPDATE_HTTP_PROXY_MSG = 29;
1476 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1477 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1478 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1479 static final int REPORT_MEM_USAGE_MSG = 33;
1480 static final int REPORT_USER_SWITCH_MSG = 34;
1481 static final int CONTINUE_USER_SWITCH_MSG = 35;
1482 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1483 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1484 static final int PERSIST_URI_GRANTS_MSG = 38;
1485 static final int REQUEST_ALL_PSS_MSG = 39;
1486 static final int START_PROFILES_MSG = 40;
1487 static final int UPDATE_TIME = 41;
1488 static final int SYSTEM_USER_START_MSG = 42;
1489 static final int SYSTEM_USER_CURRENT_MSG = 43;
1490 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1491 static final int FINISH_BOOTING_MSG = 45;
1492 static final int START_USER_SWITCH_UI_MSG = 46;
1493 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1494 static final int DISMISS_DIALOG_UI_MSG = 48;
1495 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1496 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1497 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1498 static final int DELETE_DUMPHEAP_MSG = 52;
1499 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1500 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1501 static final int REPORT_TIME_TRACKER_MSG = 55;
1502 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1503 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1504 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1505 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1506 static final int IDLE_UIDS_MSG = 60;
1507 static final int SYSTEM_USER_UNLOCK_MSG = 61;
1508 static final int LOG_STACK_STATE = 62;
1509 static final int VR_MODE_CHANGE_MSG = 63;
1510 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1511 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1512 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1513 static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1514 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1515 static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1517 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1518 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1519 static final int FIRST_COMPAT_MODE_MSG = 300;
1520 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1522 static ServiceThread sKillThread = null;
1523 static KillHandler sKillHandler = null;
1525 CompatModeDialog mCompatModeDialog;
1526 long mLastMemUsageReportTime = 0;
1529 * Flag whether the current user is a "monkey", i.e. whether
1530 * the UI is driven by a UI automation tool.
1532 private boolean mUserIsMonkey;
1534 /** Flag whether the device has a Recents UI */
1535 boolean mHasRecents;
1537 /** The dimensions of the thumbnails in the Recents UI. */
1538 int mThumbnailWidth;
1539 int mThumbnailHeight;
1540 float mFullscreenThumbnailScale;
1542 final ServiceThread mHandlerThread;
1543 final MainHandler mHandler;
1544 final UiHandler mUiHandler;
1546 PackageManagerInternal mPackageManagerInt;
1548 // VoiceInteraction session ID that changes for each new request except when
1549 // being called for multiwindow assist in a single session.
1550 private int mViSessionId = 1000;
1552 final class KillHandler extends Handler {
1553 static final int KILL_PROCESS_GROUP_MSG = 4000;
1555 public KillHandler(Looper looper) {
1556 super(looper, null, true);
1560 public void handleMessage(Message msg) {
1562 case KILL_PROCESS_GROUP_MSG:
1564 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1565 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1566 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1571 super.handleMessage(msg);
1576 final class UiHandler extends Handler {
1577 public UiHandler() {
1578 super(com.android.server.UiThread.get().getLooper(), null, true);
1582 public void handleMessage(Message msg) {
1584 case SHOW_ERROR_UI_MSG: {
1585 mAppErrors.handleShowAppErrorUi(msg);
1586 ensureBootCompleted();
1588 case SHOW_NOT_RESPONDING_UI_MSG: {
1589 mAppErrors.handleShowAnrUi(msg);
1590 ensureBootCompleted();
1592 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1593 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1594 synchronized (ActivityManagerService.this) {
1595 ProcessRecord proc = (ProcessRecord) data.get("app");
1597 Slog.e(TAG, "App not found when showing strict mode dialog.");
1600 if (proc.crashDialog != null) {
1601 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1604 AppErrorResult res = (AppErrorResult) data.get("result");
1605 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1606 Dialog d = new StrictModeViolationDialog(mContext,
1607 ActivityManagerService.this, res, proc);
1609 proc.crashDialog = d;
1611 // The device is asleep, so just pretend that the user
1612 // saw a crash dialog and hit "force quit".
1616 ensureBootCompleted();
1618 case SHOW_FACTORY_ERROR_UI_MSG: {
1619 Dialog d = new FactoryErrorDialog(
1620 mContext, msg.getData().getCharSequence("msg"));
1622 ensureBootCompleted();
1624 case WAIT_FOR_DEBUGGER_UI_MSG: {
1625 synchronized (ActivityManagerService.this) {
1626 ProcessRecord app = (ProcessRecord)msg.obj;
1627 if (msg.arg1 != 0) {
1628 if (!app.waitedForDebugger) {
1629 Dialog d = new AppWaitingForDebuggerDialog(
1630 ActivityManagerService.this,
1633 app.waitedForDebugger = true;
1637 if (app.waitDialog != null) {
1638 app.waitDialog.dismiss();
1639 app.waitDialog = null;
1644 case SHOW_UID_ERROR_UI_MSG: {
1646 AlertDialog d = new BaseErrorDialog(mContext);
1647 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1648 d.setCancelable(false);
1649 d.setTitle(mContext.getText(R.string.android_system_label));
1650 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1651 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1652 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1656 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1658 AlertDialog d = new BaseErrorDialog(mContext);
1659 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1660 d.setCancelable(false);
1661 d.setTitle(mContext.getText(R.string.android_system_label));
1662 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1663 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1664 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1668 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1669 synchronized (ActivityManagerService.this) {
1670 ActivityRecord ar = (ActivityRecord) msg.obj;
1671 if (mCompatModeDialog != null) {
1672 if (mCompatModeDialog.mAppInfo.packageName.equals(
1673 ar.info.applicationInfo.packageName)) {
1676 mCompatModeDialog.dismiss();
1677 mCompatModeDialog = null;
1679 if (ar != null && false) {
1680 if (mCompatModePackages.getPackageAskCompatModeLocked(
1682 int mode = mCompatModePackages.computeCompatModeLocked(
1683 ar.info.applicationInfo);
1684 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1685 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1686 mCompatModeDialog = new CompatModeDialog(
1687 ActivityManagerService.this, mContext,
1688 ar.info.applicationInfo);
1689 mCompatModeDialog.show();
1696 case START_USER_SWITCH_UI_MSG: {
1697 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1700 case DISMISS_DIALOG_UI_MSG: {
1701 final Dialog d = (Dialog) msg.obj;
1705 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1706 dispatchProcessesChanged();
1709 case DISPATCH_PROCESS_DIED_UI_MSG: {
1710 final int pid = msg.arg1;
1711 final int uid = msg.arg2;
1712 dispatchProcessDied(pid, uid);
1715 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1716 dispatchUidsChanged();
1722 final class MainHandler extends Handler {
1723 public MainHandler(Looper looper) {
1724 super(looper, null, true);
1728 public void handleMessage(Message msg) {
1730 case UPDATE_CONFIGURATION_MSG: {
1731 final ContentResolver resolver = mContext.getContentResolver();
1732 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1735 case GC_BACKGROUND_PROCESSES_MSG: {
1736 synchronized (ActivityManagerService.this) {
1737 performAppGcsIfAppropriateLocked();
1740 case SERVICE_TIMEOUT_MSG: {
1743 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1745 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1748 mServices.serviceTimeout((ProcessRecord)msg.obj);
1750 case UPDATE_TIME_ZONE: {
1751 synchronized (ActivityManagerService.this) {
1752 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1753 ProcessRecord r = mLruProcesses.get(i);
1754 if (r.thread != null) {
1756 r.thread.updateTimeZone();
1757 } catch (RemoteException ex) {
1758 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1764 case CLEAR_DNS_CACHE_MSG: {
1765 synchronized (ActivityManagerService.this) {
1766 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1767 ProcessRecord r = mLruProcesses.get(i);
1768 if (r.thread != null) {
1770 r.thread.clearDnsCache();
1771 } catch (RemoteException ex) {
1772 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1778 case UPDATE_HTTP_PROXY_MSG: {
1779 ProxyInfo proxy = (ProxyInfo)msg.obj;
1782 String exclList = "";
1783 Uri pacFileUrl = Uri.EMPTY;
1784 if (proxy != null) {
1785 host = proxy.getHost();
1786 port = Integer.toString(proxy.getPort());
1787 exclList = proxy.getExclusionListAsString();
1788 pacFileUrl = proxy.getPacFileUrl();
1790 synchronized (ActivityManagerService.this) {
1791 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1792 ProcessRecord r = mLruProcesses.get(i);
1793 if (r.thread != null) {
1795 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1796 } catch (RemoteException ex) {
1797 Slog.w(TAG, "Failed to update http proxy for: " +
1798 r.info.processName);
1804 case PROC_START_TIMEOUT_MSG: {
1807 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1809 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1812 ProcessRecord app = (ProcessRecord)msg.obj;
1813 synchronized (ActivityManagerService.this) {
1814 processStartTimedOutLocked(app);
1817 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1818 ProcessRecord app = (ProcessRecord)msg.obj;
1819 synchronized (ActivityManagerService.this) {
1820 processContentProviderPublishTimedOutLocked(app);
1823 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1824 synchronized (ActivityManagerService.this) {
1825 mActivityStarter.doPendingActivityLaunchesLocked(true);
1828 case KILL_APPLICATION_MSG: {
1829 synchronized (ActivityManagerService.this) {
1830 int appid = msg.arg1;
1831 boolean restart = (msg.arg2 == 1);
1832 Bundle bundle = (Bundle)msg.obj;
1833 String pkg = bundle.getString("pkg");
1834 String reason = bundle.getString("reason");
1835 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1836 false, UserHandle.USER_ALL, reason);
1839 case FINALIZE_PENDING_INTENT_MSG: {
1840 ((PendingIntentRecord)msg.obj).completeFinalize();
1842 case POST_HEAVY_NOTIFICATION_MSG: {
1843 INotificationManager inm = NotificationManager.getService();
1848 ActivityRecord root = (ActivityRecord)msg.obj;
1849 ProcessRecord process = root.app;
1850 if (process == null) {
1855 Context context = mContext.createPackageContext(process.info.packageName, 0);
1856 String text = mContext.getString(R.string.heavy_weight_notification,
1857 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1858 Notification notification = new Notification.Builder(context)
1859 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1863 .setColor(mContext.getColor(
1864 com.android.internal.R.color.system_notification_accent_color))
1865 .setContentTitle(text)
1867 mContext.getText(R.string.heavy_weight_notification_detail))
1868 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1869 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1870 new UserHandle(root.userId)))
1873 int[] outId = new int[1];
1874 inm.enqueueNotificationWithTag("android", "android", null,
1875 R.string.heavy_weight_notification,
1876 notification, outId, root.userId);
1877 } catch (RuntimeException e) {
1878 Slog.w(ActivityManagerService.TAG,
1879 "Error showing notification for heavy-weight app", e);
1880 } catch (RemoteException e) {
1882 } catch (NameNotFoundException e) {
1883 Slog.w(TAG, "Unable to create context for heavy notification", e);
1886 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1887 INotificationManager inm = NotificationManager.getService();
1892 inm.cancelNotificationWithTag("android", null,
1893 R.string.heavy_weight_notification, msg.arg1);
1894 } catch (RuntimeException e) {
1895 Slog.w(ActivityManagerService.TAG,
1896 "Error canceling notification for service", e);
1897 } catch (RemoteException e) {
1900 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1901 synchronized (ActivityManagerService.this) {
1902 checkExcessivePowerUsageLocked(true);
1903 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1904 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1905 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1908 case REPORT_MEM_USAGE_MSG: {
1909 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1910 Thread thread = new Thread() {
1911 @Override public void run() {
1912 reportMemUsage(memInfos);
1918 case REPORT_USER_SWITCH_MSG: {
1919 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1922 case CONTINUE_USER_SWITCH_MSG: {
1923 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1926 case USER_SWITCH_TIMEOUT_MSG: {
1927 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1930 case IMMERSIVE_MODE_LOCK_MSG: {
1931 final boolean nextState = (msg.arg1 != 0);
1932 if (mUpdateLock.isHeld() != nextState) {
1933 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1934 "Applying new update lock state '" + nextState
1935 + "' for " + (ActivityRecord)msg.obj);
1937 mUpdateLock.acquire();
1939 mUpdateLock.release();
1944 case PERSIST_URI_GRANTS_MSG: {
1945 writeGrantedUriPermissions();
1948 case REQUEST_ALL_PSS_MSG: {
1949 synchronized (ActivityManagerService.this) {
1950 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1954 case START_PROFILES_MSG: {
1955 synchronized (ActivityManagerService.this) {
1956 mUserController.startProfilesLocked();
1961 synchronized (ActivityManagerService.this) {
1962 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1963 ProcessRecord r = mLruProcesses.get(i);
1964 if (r.thread != null) {
1966 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1967 } catch (RemoteException ex) {
1968 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1975 case SYSTEM_USER_START_MSG: {
1976 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1977 Integer.toString(msg.arg1), msg.arg1);
1978 mSystemServiceManager.startUser(msg.arg1);
1981 case SYSTEM_USER_UNLOCK_MSG: {
1982 final int userId = msg.arg1;
1983 mSystemServiceManager.unlockUser(userId);
1984 synchronized (ActivityManagerService.this) {
1985 mRecentTasks.loadUserRecentsLocked(userId);
1987 if (userId == UserHandle.USER_SYSTEM) {
1988 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1990 installEncryptionUnawareProviders(userId);
1991 mUserController.finishUserUnlocked((UserState) msg.obj);
1994 case SYSTEM_USER_CURRENT_MSG: {
1995 mBatteryStatsService.noteEvent(
1996 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1997 Integer.toString(msg.arg2), msg.arg2);
1998 mBatteryStatsService.noteEvent(
1999 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2000 Integer.toString(msg.arg1), msg.arg1);
2001 mSystemServiceManager.switchUser(msg.arg1);
2004 case ENTER_ANIMATION_COMPLETE_MSG: {
2005 synchronized (ActivityManagerService.this) {
2006 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2007 if (r != null && r.app != null && r.app.thread != null) {
2009 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2010 } catch (RemoteException e) {
2016 case FINISH_BOOTING_MSG: {
2017 if (msg.arg1 != 0) {
2018 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2020 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2022 if (msg.arg2 != 0) {
2023 enableScreenAfterBoot();
2027 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2029 Locale l = (Locale) msg.obj;
2030 IBinder service = ServiceManager.getService("mount");
2031 IMountService mountService = IMountService.Stub.asInterface(service);
2032 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2033 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2034 } catch (RemoteException e) {
2035 Log.e(TAG, "Error storing locale for decryption UI", e);
2039 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2040 synchronized (ActivityManagerService.this) {
2041 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2043 // Make a one-way callback to the listener
2044 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2045 } catch (RemoteException e){
2046 // Handled by the RemoteCallbackList
2049 mTaskStackListeners.finishBroadcast();
2053 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2054 synchronized (ActivityManagerService.this) {
2055 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2057 // Make a one-way callback to the listener
2058 mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2059 } catch (RemoteException e){
2060 // Handled by the RemoteCallbackList
2063 mTaskStackListeners.finishBroadcast();
2067 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2068 synchronized (ActivityManagerService.this) {
2069 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2071 // Make a one-way callback to the listener
2072 mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2073 } catch (RemoteException e){
2074 // Handled by the RemoteCallbackList
2077 mTaskStackListeners.finishBroadcast();
2081 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2082 synchronized (ActivityManagerService.this) {
2083 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2085 // Make a one-way callback to the listener
2086 mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2087 } catch (RemoteException e){
2088 // Handled by the RemoteCallbackList
2091 mTaskStackListeners.finishBroadcast();
2095 case NOTIFY_FORCED_RESIZABLE_MSG: {
2096 synchronized (ActivityManagerService.this) {
2097 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2099 // Make a one-way callback to the listener
2100 mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2101 (String) msg.obj, msg.arg1);
2102 } catch (RemoteException e){
2103 // Handled by the RemoteCallbackList
2106 mTaskStackListeners.finishBroadcast();
2110 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2111 synchronized (ActivityManagerService.this) {
2112 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2114 // Make a one-way callback to the listener
2115 mTaskStackListeners.getBroadcastItem(i)
2116 .onActivityDismissingDockedStack();
2117 } catch (RemoteException e){
2118 // Handled by the RemoteCallbackList
2121 mTaskStackListeners.finishBroadcast();
2125 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2126 final int uid = msg.arg1;
2127 final byte[] firstPacket = (byte[]) msg.obj;
2129 synchronized (mPidsSelfLocked) {
2130 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2131 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2134 p.thread.notifyCleartextNetwork(firstPacket);
2135 } catch (RemoteException ignored) {
2142 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2143 final String procName;
2145 final long memLimit;
2146 final String reportPackage;
2147 synchronized (ActivityManagerService.this) {
2148 procName = mMemWatchDumpProcName;
2149 uid = mMemWatchDumpUid;
2150 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2152 val = mMemWatchProcesses.get(procName, 0);
2155 memLimit = val.first;
2156 reportPackage = val.second;
2159 reportPackage = null;
2162 if (procName == null) {
2166 if (DEBUG_PSS) Slog.d(TAG_PSS,
2167 "Showing dump heap notification from " + procName + "/" + uid);
2169 INotificationManager inm = NotificationManager.getService();
2174 String text = mContext.getString(R.string.dump_heap_notification, procName);
2177 Intent deleteIntent = new Intent();
2178 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2179 Intent intent = new Intent();
2180 intent.setClassName("android", DumpHeapActivity.class.getName());
2181 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2182 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2183 if (reportPackage != null) {
2184 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2186 int userId = UserHandle.getUserId(uid);
2187 Notification notification = new Notification.Builder(mContext)
2188 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2191 .setAutoCancel(true)
2193 .setColor(mContext.getColor(
2194 com.android.internal.R.color.system_notification_accent_color))
2195 .setContentTitle(text)
2197 mContext.getText(R.string.dump_heap_notification_detail))
2198 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2199 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2200 new UserHandle(userId)))
2201 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2202 deleteIntent, 0, UserHandle.SYSTEM))
2206 int[] outId = new int[1];
2207 inm.enqueueNotificationWithTag("android", "android", null,
2208 R.string.dump_heap_notification,
2209 notification, outId, userId);
2210 } catch (RuntimeException e) {
2211 Slog.w(ActivityManagerService.TAG,
2212 "Error showing notification for dump heap", e);
2213 } catch (RemoteException e) {
2216 case DELETE_DUMPHEAP_MSG: {
2217 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2218 DumpHeapActivity.JAVA_URI,
2219 Intent.FLAG_GRANT_READ_URI_PERMISSION
2220 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2221 UserHandle.myUserId());
2222 synchronized (ActivityManagerService.this) {
2223 mMemWatchDumpFile = null;
2224 mMemWatchDumpProcName = null;
2225 mMemWatchDumpPid = -1;
2226 mMemWatchDumpUid = -1;
2229 case FOREGROUND_PROFILE_CHANGED_MSG: {
2230 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2232 case REPORT_TIME_TRACKER_MSG: {
2233 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2234 tracker.deliverResult(mContext);
2236 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2237 mUserController.dispatchUserSwitchComplete(msg.arg1);
2239 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2240 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2242 connection.shutdown();
2243 } catch (RemoteException e) {
2244 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2246 // Only a UiAutomation can set this flag and now that
2247 // it is finished we make sure it is reset to its default.
2248 mUserIsMonkey = false;
2250 case APP_BOOST_DEACTIVATE_MSG: {
2251 synchronized(ActivityManagerService.this) {
2253 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2254 nativeMigrateFromBoost();
2256 mBoostStartTime = 0;
2258 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2259 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2264 case IDLE_UIDS_MSG: {
2267 case LOG_STACK_STATE: {
2268 synchronized (ActivityManagerService.this) {
2269 mStackSupervisor.logStackState();
2272 case VR_MODE_CHANGE_MSG: {
2273 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2274 final ActivityRecord r = (ActivityRecord) msg.obj;
2276 ComponentName requestedPackage;
2277 ComponentName callingPackage;
2279 synchronized (ActivityManagerService.this) {
2280 vrMode = r.requestedVrComponent != null;
2281 requestedPackage = r.requestedVrComponent;
2283 callingPackage = r.info.getComponentName();
2284 if (mInVrMode != vrMode) {
2286 mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2289 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2291 case VR_MODE_APPLY_IF_NEEDED_MSG: {
2292 final ActivityRecord r = (ActivityRecord) msg.obj;
2293 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2295 VrManagerInternal vrService =
2296 LocalServices.getService(VrManagerInternal.class);
2297 boolean enable = msg.arg1 == 1;
2298 vrService.setVrMode(enable, r.requestedVrComponent, r.userId,
2299 r.info.getComponentName());
2306 static final int COLLECT_PSS_BG_MSG = 1;
2308 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2310 public void handleMessage(Message msg) {
2312 case COLLECT_PSS_BG_MSG: {
2313 long start = SystemClock.uptimeMillis();
2314 MemInfoReader memInfo = null;
2315 synchronized (ActivityManagerService.this) {
2316 if (mFullPssPending) {
2317 mFullPssPending = false;
2318 memInfo = new MemInfoReader();
2321 if (memInfo != null) {
2322 updateCpuStatsNow();
2323 long nativeTotalPss = 0;
2324 synchronized (mProcessCpuTracker) {
2325 final int N = mProcessCpuTracker.countStats();
2326 for (int j=0; j<N; j++) {
2327 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2328 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2329 // This is definitely an application process; skip it.
2332 synchronized (mPidsSelfLocked) {
2333 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2334 // This is one of our own processes; skip it.
2338 nativeTotalPss += Debug.getPss(st.pid, null, null);
2341 memInfo.readMemInfo();
2342 synchronized (ActivityManagerService.this) {
2343 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2344 + (SystemClock.uptimeMillis()-start) + "ms");
2345 final long cachedKb = memInfo.getCachedSizeKb();
2346 final long freeKb = memInfo.getFreeSizeKb();
2347 final long zramKb = memInfo.getZramTotalSizeKb();
2348 final long kernelKb = memInfo.getKernelUsedSizeKb();
2349 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2350 kernelKb*1024, nativeTotalPss*1024);
2351 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2357 long[] tmp = new long[2];
2363 synchronized (ActivityManagerService.this) {
2364 if (mPendingPssProcesses.size() <= 0) {
2365 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2366 "Collected PSS of " + num + " processes in "
2367 + (SystemClock.uptimeMillis() - start) + "ms");
2368 mPendingPssProcesses.clear();
2371 proc = mPendingPssProcesses.remove(0);
2372 procState = proc.pssProcState;
2373 lastPssTime = proc.lastPssTime;
2374 if (proc.thread != null && procState == proc.setProcState
2375 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2376 < SystemClock.uptimeMillis()) {
2384 long pss = Debug.getPss(pid, tmp, null);
2385 synchronized (ActivityManagerService.this) {
2386 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2387 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2389 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2390 SystemClock.uptimeMillis());
2400 public void setSystemProcess() {
2402 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2403 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2404 ServiceManager.addService("meminfo", new MemBinder(this));
2405 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2406 ServiceManager.addService("dbinfo", new DbBinder(this));
2407 if (MONITOR_CPU_USAGE) {
2408 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2410 ServiceManager.addService("permission", new PermissionController(this));
2411 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2413 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2414 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2415 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2417 synchronized (this) {
2418 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2419 app.persistent = true;
2421 app.maxAdj = ProcessList.SYSTEM_ADJ;
2422 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2423 synchronized (mPidsSelfLocked) {
2424 mPidsSelfLocked.put(app.pid, app);
2426 updateLruProcessLocked(app, false, null);
2427 updateOomAdjLocked();
2429 } catch (PackageManager.NameNotFoundException e) {
2430 throw new RuntimeException(
2431 "Unable to find android system package", e);
2435 public void setWindowManager(WindowManagerService wm) {
2436 mWindowManager = wm;
2437 mStackSupervisor.setWindowManager(wm);
2438 mActivityStarter.setWindowManager(wm);
2441 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2442 mUsageStatsService = usageStatsManager;
2445 public void startObservingNativeCrashes() {
2446 final NativeCrashListener ncl = new NativeCrashListener(this);
2450 public IAppOpsService getAppOpsService() {
2451 return mAppOpsService;
2454 static class MemBinder extends Binder {
2455 ActivityManagerService mActivityManagerService;
2456 MemBinder(ActivityManagerService activityManagerService) {
2457 mActivityManagerService = activityManagerService;
2461 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2462 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2463 != PackageManager.PERMISSION_GRANTED) {
2464 pw.println("Permission Denial: can't dump meminfo from from pid="
2465 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2466 + " without permission " + android.Manifest.permission.DUMP);
2470 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2474 static class GraphicsBinder extends Binder {
2475 ActivityManagerService mActivityManagerService;
2476 GraphicsBinder(ActivityManagerService activityManagerService) {
2477 mActivityManagerService = activityManagerService;
2481 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2482 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2483 != PackageManager.PERMISSION_GRANTED) {
2484 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2485 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2486 + " without permission " + android.Manifest.permission.DUMP);
2490 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2494 static class DbBinder extends Binder {
2495 ActivityManagerService mActivityManagerService;
2496 DbBinder(ActivityManagerService activityManagerService) {
2497 mActivityManagerService = activityManagerService;
2501 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2502 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2503 != PackageManager.PERMISSION_GRANTED) {
2504 pw.println("Permission Denial: can't dump dbinfo from from pid="
2505 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2506 + " without permission " + android.Manifest.permission.DUMP);
2510 mActivityManagerService.dumpDbInfo(fd, pw, args);
2514 static class CpuBinder extends Binder {
2515 ActivityManagerService mActivityManagerService;
2516 CpuBinder(ActivityManagerService activityManagerService) {
2517 mActivityManagerService = activityManagerService;
2521 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2522 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2523 != PackageManager.PERMISSION_GRANTED) {
2524 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2525 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2526 + " without permission " + android.Manifest.permission.DUMP);
2530 synchronized (mActivityManagerService.mProcessCpuTracker) {
2531 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2532 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2533 SystemClock.uptimeMillis()));
2538 public static final class Lifecycle extends SystemService {
2539 private final ActivityManagerService mService;
2541 public Lifecycle(Context context) {
2543 mService = new ActivityManagerService(context);
2547 public void onStart() {
2551 public ActivityManagerService getService() {
2556 // Note: This method is invoked on the main thread but may need to attach various
2557 // handlers to other threads. So take care to be explicit about the looper.
2558 public ActivityManagerService(Context systemContext) {
2559 mContext = systemContext;
2560 mFactoryTest = FactoryTest.getMode();
2561 mSystemThread = ActivityThread.currentActivityThread();
2563 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2565 mHandlerThread = new ServiceThread(TAG,
2566 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2567 mHandlerThread.start();
2568 mHandler = new MainHandler(mHandlerThread.getLooper());
2569 mUiHandler = new UiHandler();
2571 /* static; one-time init here */
2572 if (sKillHandler == null) {
2573 sKillThread = new ServiceThread(TAG + ":kill",
2574 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2575 sKillThread.start();
2576 sKillHandler = new KillHandler(sKillThread.getLooper());
2579 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2580 "foreground", BROADCAST_FG_TIMEOUT, false);
2581 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2582 "background", BROADCAST_BG_TIMEOUT, true);
2583 mBroadcastQueues[0] = mFgBroadcastQueue;
2584 mBroadcastQueues[1] = mBgBroadcastQueue;
2586 mServices = new ActiveServices(this);
2587 mProviderMap = new ProviderMap(this);
2588 mAppErrors = new AppErrors(mContext, this);
2590 // TODO: Move creation of battery stats service outside of activity manager service.
2591 File dataDir = Environment.getDataDirectory();
2592 File systemDir = new File(dataDir, "system");
2594 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2595 mBatteryStatsService.getActiveStatistics().readLocked();
2596 mBatteryStatsService.scheduleWriteToDisk();
2597 mOnBattery = DEBUG_POWER ? true
2598 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2599 mBatteryStatsService.getActiveStatistics().setCallback(this);
2601 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2603 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2604 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2605 new IAppOpsCallback.Stub() {
2606 @Override public void opChanged(int op, int uid, String packageName) {
2607 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2608 if (mAppOpsService.checkOperation(op, uid, packageName)
2609 != AppOpsManager.MODE_ALLOWED) {
2610 runInBackgroundDisabled(uid);
2616 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2618 mUserController = new UserController(this);
2620 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2621 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2623 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2625 mConfiguration.setToDefaults();
2626 mConfiguration.setLocales(LocaleList.getDefault());
2628 mConfigurationSeq = mConfiguration.seq = 1;
2629 mProcessCpuTracker.init();
2631 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2632 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2633 mStackSupervisor = new ActivityStackSupervisor(this);
2634 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2635 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2637 mProcessCpuThread = new Thread("CpuTracker") {
2643 synchronized(this) {
2644 final long now = SystemClock.uptimeMillis();
2645 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2646 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2647 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2648 // + ", write delay=" + nextWriteDelay);
2649 if (nextWriteDelay < nextCpuDelay) {
2650 nextCpuDelay = nextWriteDelay;
2652 if (nextCpuDelay > 0) {
2653 mProcessCpuMutexFree.set(true);
2654 this.wait(nextCpuDelay);
2657 } catch (InterruptedException e) {
2659 updateCpuStatsNow();
2660 } catch (Exception e) {
2661 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2667 Watchdog.getInstance().addMonitor(this);
2668 Watchdog.getInstance().addThread(mHandler);
2671 public void setSystemServiceManager(SystemServiceManager mgr) {
2672 mSystemServiceManager = mgr;
2675 public void setInstaller(Installer installer) {
2676 mInstaller = installer;
2679 private void start() {
2680 Process.removeAllProcessGroups();
2681 mProcessCpuThread.start();
2683 mBatteryStatsService.publish(mContext);
2684 mAppOpsService.publish(mContext);
2685 Slog.d("AppOps", "AppOpsService published");
2686 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2689 void onUserStoppedLocked(int userId) {
2690 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2693 public void initPowerManagement() {
2694 mStackSupervisor.initPowerManagement();
2695 mBatteryStatsService.initPowerManagement();
2696 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2697 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2698 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2699 mVoiceWakeLock.setReferenceCounted(false);
2703 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2704 throws RemoteException {
2705 if (code == SYSPROPS_TRANSACTION) {
2706 // We need to tell all apps about the system property change.
2707 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2708 synchronized(this) {
2709 final int NP = mProcessNames.getMap().size();
2710 for (int ip=0; ip<NP; ip++) {
2711 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2712 final int NA = apps.size();
2713 for (int ia=0; ia<NA; ia++) {
2714 ProcessRecord app = apps.valueAt(ia);
2715 if (app.thread != null) {
2716 procs.add(app.thread.asBinder());
2722 int N = procs.size();
2723 for (int i=0; i<N; i++) {
2724 Parcel data2 = Parcel.obtain();
2726 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2727 } catch (RemoteException e) {
2733 return super.onTransact(code, data, reply, flags);
2734 } catch (RuntimeException e) {
2735 // The activity manager only throws security exceptions, so let's
2737 if (!(e instanceof SecurityException)) {
2738 Slog.wtf(TAG, "Activity Manager Crash", e);
2744 void updateCpuStats() {
2745 final long now = SystemClock.uptimeMillis();
2746 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2749 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2750 synchronized (mProcessCpuThread) {
2751 mProcessCpuThread.notify();
2756 void updateCpuStatsNow() {
2757 synchronized (mProcessCpuTracker) {
2758 mProcessCpuMutexFree.set(false);
2759 final long now = SystemClock.uptimeMillis();
2760 boolean haveNewCpuStats = false;
2762 if (MONITOR_CPU_USAGE &&
2763 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2764 mLastCpuTime.set(now);
2765 mProcessCpuTracker.update();
2766 if (mProcessCpuTracker.hasGoodLastStats()) {
2767 haveNewCpuStats = true;
2768 //Slog.i(TAG, mProcessCpu.printCurrentState());
2769 //Slog.i(TAG, "Total CPU usage: "
2770 // + mProcessCpu.getTotalCpuPercent() + "%");
2772 // Slog the cpu usage if the property is set.
2773 if ("true".equals(SystemProperties.get("events.cpu"))) {
2774 int user = mProcessCpuTracker.getLastUserTime();
2775 int system = mProcessCpuTracker.getLastSystemTime();
2776 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2777 int irq = mProcessCpuTracker.getLastIrqTime();
2778 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2779 int idle = mProcessCpuTracker.getLastIdleTime();
2781 int total = user + system + iowait + irq + softIrq + idle;
2782 if (total == 0) total = 1;
2784 EventLog.writeEvent(EventLogTags.CPU,
2785 ((user+system+iowait+irq+softIrq) * 100) / total,
2786 (user * 100) / total,
2787 (system * 100) / total,
2788 (iowait * 100) / total,
2789 (irq * 100) / total,
2790 (softIrq * 100) / total);
2795 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2796 synchronized(bstats) {
2797 synchronized(mPidsSelfLocked) {
2798 if (haveNewCpuStats) {
2799 if (bstats.startAddingCpuLocked()) {
2802 final int N = mProcessCpuTracker.countStats();
2803 for (int i=0; i<N; i++) {
2804 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2808 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2809 totalUTime += st.rel_utime;
2810 totalSTime += st.rel_stime;
2812 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2813 if (ps == null || !ps.isActive()) {
2814 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2815 pr.info.uid, pr.processName);
2817 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2818 pr.curCpuTime += st.rel_utime + st.rel_stime;
2820 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2821 if (ps == null || !ps.isActive()) {
2822 st.batteryStats = ps = bstats.getProcessStatsLocked(
2823 bstats.mapUid(st.uid), st.name);
2825 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2828 final int userTime = mProcessCpuTracker.getLastUserTime();
2829 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2830 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2831 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2832 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2833 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2834 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2835 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2840 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2841 mLastWriteTime = now;
2842 mBatteryStatsService.scheduleWriteToDisk();
2849 public void batteryNeedsCpuUpdate() {
2850 updateCpuStatsNow();
2854 public void batteryPowerChanged(boolean onBattery) {
2855 // When plugging in, update the CPU stats first before changing
2857 updateCpuStatsNow();
2858 synchronized (this) {
2859 synchronized(mPidsSelfLocked) {
2860 mOnBattery = DEBUG_POWER ? true : onBattery;
2866 public void batterySendBroadcast(Intent intent) {
2867 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2868 AppOpsManager.OP_NONE, null, false, false,
2869 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2873 * Initialize the application bind args. These are passed to each
2874 * process when the bindApplication() IPC is sent to the process. They're
2875 * lazily setup to make sure the services are running when they're asked for.
2877 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2878 if (mAppBindArgs == null) {
2879 mAppBindArgs = new HashMap<>();
2881 // Isolated processes won't get this optimization, so that we don't
2882 // violate the rules about which services they have access to.
2884 // Setup the application init args
2885 mAppBindArgs.put("package", ServiceManager.getService("package"));
2886 mAppBindArgs.put("window", ServiceManager.getService("window"));
2887 mAppBindArgs.put(Context.ALARM_SERVICE,
2888 ServiceManager.getService(Context.ALARM_SERVICE));
2891 return mAppBindArgs;
2894 boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2895 if (r == null || mFocusedActivity == r) {
2899 if (!r.isFocusable()) {
2900 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2904 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2906 final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2907 if (wasDoingSetFocusedActivity) Slog.w(TAG,
2908 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2909 mDoingSetFocusedActivity = true;
2911 final ActivityRecord last = mFocusedActivity;
2912 mFocusedActivity = r;
2913 if (r.task.isApplicationTask()) {
2914 if (mCurAppTimeTracker != r.appTimeTracker) {
2915 // We are switching app tracking. Complete the current one.
2916 if (mCurAppTimeTracker != null) {
2917 mCurAppTimeTracker.stop();
2918 mHandler.obtainMessage(
2919 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2920 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2921 mCurAppTimeTracker = null;
2923 if (r.appTimeTracker != null) {
2924 mCurAppTimeTracker = r.appTimeTracker;
2925 startTimeTrackingFocusedActivityLocked();
2928 startTimeTrackingFocusedActivityLocked();
2931 r.appTimeTracker = null;
2933 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2934 // TODO: Probably not, because we don't want to resume voice on switching
2935 // back to this activity
2936 if (r.task.voiceInteractor != null) {
2937 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2939 finishRunningVoiceLocked();
2940 IVoiceInteractionSession session;
2941 if (last != null && ((session = last.task.voiceSession) != null
2942 || (session = last.voiceSession) != null)) {
2943 // We had been in a voice interaction session, but now focused has
2944 // move to something different. Just finish the session, we can't
2945 // return to it and retain the proper state and synchronization with
2946 // the voice interaction service.
2947 finishVoiceTask(session);
2950 if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2951 mWindowManager.setFocusedApp(r.appToken, true);
2953 applyUpdateLockStateLocked(r);
2954 applyUpdateVrModeLocked(r);
2955 if (mFocusedActivity.userId != mLastFocusedUserId) {
2956 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2957 mHandler.obtainMessage(
2958 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2959 mLastFocusedUserId = mFocusedActivity.userId;
2962 // Log a warning if the focused app is changed during the process. This could
2963 // indicate a problem of the focus setting logic!
2964 if (mFocusedActivity != r) Slog.w(TAG,
2965 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2966 mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2968 EventLogTags.writeAmFocusedActivity(
2969 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2970 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2975 final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2976 if (mFocusedActivity != goingAway) {
2980 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2981 if (focusedStack != null) {
2982 final ActivityRecord top = focusedStack.topActivity();
2983 if (top != null && top.userId != mLastFocusedUserId) {
2984 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2985 mHandler.sendMessage(
2986 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2987 mLastFocusedUserId = top.userId;
2991 // Try to move focus to another activity if possible.
2992 if (setFocusedActivityLocked(
2993 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2997 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2998 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2999 mFocusedActivity = null;
3000 EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3004 public void setFocusedStack(int stackId) {
3005 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3006 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3007 final long callingId = Binder.clearCallingIdentity();
3009 synchronized (this) {
3010 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3011 if (stack == null) {
3014 final ActivityRecord r = stack.topRunningActivityLocked();
3015 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3016 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3020 Binder.restoreCallingIdentity(callingId);
3025 public void setFocusedTask(int taskId) {
3026 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3027 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3028 final long callingId = Binder.clearCallingIdentity();
3030 synchronized (this) {
3031 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3035 final ActivityRecord r = task.topRunningActivityLocked();
3036 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3037 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3041 Binder.restoreCallingIdentity(callingId);
3045 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3047 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3048 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3049 synchronized (this) {
3050 if (listener != null) {
3051 mTaskStackListeners.register(listener);
3057 public void notifyActivityDrawn(IBinder token) {
3058 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3059 synchronized (this) {
3060 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3062 r.task.stack.notifyActivityDrawnLocked(r);
3067 final void applyUpdateLockStateLocked(ActivityRecord r) {
3068 // Modifications to the UpdateLock state are done on our handler, outside
3069 // the activity manager's locks. The new state is determined based on the
3070 // state *now* of the relevant activity record. The object is passed to
3071 // the handler solely for logging detail, not to be consulted/modified.
3072 final boolean nextState = r != null && r.immersive;
3073 mHandler.sendMessage(
3074 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3077 final void applyUpdateVrModeLocked(ActivityRecord r) {
3078 mHandler.sendMessage(
3079 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3082 private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3083 mHandler.sendMessage(
3084 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3087 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3088 Message msg = Message.obtain();
3089 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3090 msg.obj = r.task.askedCompatMode ? null : r;
3091 mUiHandler.sendMessage(msg);
3094 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3095 String what, Object obj, ProcessRecord srcApp) {
3096 app.lastActivityTime = now;
3098 if (app.activities.size() > 0) {
3099 // Don't want to touch dependent processes that are hosting activities.
3103 int lrui = mLruProcesses.lastIndexOf(app);
3105 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3106 + what + " " + obj + " from " + srcApp);
3110 if (lrui >= index) {
3111 // Don't want to cause this to move dependent processes *back* in the
3112 // list as if they were less frequently used.
3116 if (lrui >= mLruProcessActivityStart) {
3117 // Don't want to touch dependent processes that are hosting activities.
3121 mLruProcesses.remove(lrui);
3125 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3126 + " in LRU list: " + app);
3127 mLruProcesses.add(index, app);
3131 static void killProcessGroup(int uid, int pid) {
3132 if (sKillHandler != null) {
3133 sKillHandler.sendMessage(
3134 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3136 Slog.w(TAG, "Asked to kill process group before system bringup!");
3137 Process.killProcessGroup(uid, pid);
3141 final void removeLruProcessLocked(ProcessRecord app) {
3142 int lrui = mLruProcesses.lastIndexOf(app);
3145 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3146 Process.killProcessQuiet(app.pid);
3147 killProcessGroup(app.uid, app.pid);
3149 if (lrui <= mLruProcessActivityStart) {
3150 mLruProcessActivityStart--;
3152 if (lrui <= mLruProcessServiceStart) {
3153 mLruProcessServiceStart--;
3155 mLruProcesses.remove(lrui);
3159 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3160 ProcessRecord client) {
3161 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3162 || app.treatLikeActivity;
3163 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3164 if (!activityChange && hasActivity) {
3165 // The process has activities, so we are only allowing activity-based adjustments
3166 // to move it. It should be kept in the front of the list with other
3167 // processes that have activities, and we don't want those to change their
3168 // order except due to activity operations.
3173 final long now = SystemClock.uptimeMillis();
3174 app.lastActivityTime = now;
3176 // First a quick reject: if the app is already at the position we will
3177 // put it, then there is nothing to do.
3179 final int N = mLruProcesses.size();
3180 if (N > 0 && mLruProcesses.get(N-1) == app) {
3181 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3185 if (mLruProcessServiceStart > 0
3186 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3187 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3192 int lrui = mLruProcesses.lastIndexOf(app);
3194 if (app.persistent && lrui >= 0) {
3195 // We don't care about the position of persistent processes, as long as
3196 // they are in the list.
3197 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3201 /* In progress: compute new position first, so we can avoid doing work
3202 if the process is not actually going to move. Not yet working.
3205 boolean inActivity = false, inService = false;
3207 // Process has activities, put it at the very tipsy-top.
3208 addIndex = mLruProcesses.size();
3209 nextIndex = mLruProcessServiceStart;
3211 } else if (hasService) {
3212 // Process has services, put it at the top of the service list.
3213 addIndex = mLruProcessActivityStart;
3214 nextIndex = mLruProcessServiceStart;
3218 // Process not otherwise of interest, it goes to the top of the non-service area.
3219 addIndex = mLruProcessServiceStart;
3220 if (client != null) {
3221 int clientIndex = mLruProcesses.lastIndexOf(client);
3222 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3224 if (clientIndex >= 0 && addIndex > clientIndex) {
3225 addIndex = clientIndex;
3228 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3231 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3232 + mLruProcessActivityStart + "): " + app);
3236 if (lrui < mLruProcessActivityStart) {
3237 mLruProcessActivityStart--;
3239 if (lrui < mLruProcessServiceStart) {
3240 mLruProcessServiceStart--;
3243 if (addIndex > lrui) {
3246 if (nextIndex > lrui) {
3250 mLruProcesses.remove(lrui);
3254 mLruProcesses.add(addIndex, app);
3256 mLruProcessActivityStart++;
3259 mLruProcessActivityStart++;
3265 final int N = mLruProcesses.size();
3266 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3267 // Process doesn't have activities, but has clients with
3268 // activities... move it up, but one below the top (the top
3269 // should always have a real activity).
3270 if (DEBUG_LRU) Slog.d(TAG_LRU,
3271 "Adding to second-top of LRU activity list: " + app);
3272 mLruProcesses.add(N - 1, app);
3273 // To keep it from spamming the LRU list (by making a bunch of clients),
3274 // we will push down any other entries owned by the app.
3275 final int uid = app.info.uid;
3276 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3277 ProcessRecord subProc = mLruProcesses.get(i);
3278 if (subProc.info.uid == uid) {
3279 // We want to push this one down the list. If the process after
3280 // it is for the same uid, however, don't do so, because we don't
3281 // want them internally to be re-ordered.
3282 if (mLruProcesses.get(i - 1).info.uid != uid) {
3283 if (DEBUG_LRU) Slog.d(TAG_LRU,
3284 "Pushing uid " + uid + " swapping at " + i + ": "
3285 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3286 ProcessRecord tmp = mLruProcesses.get(i);
3287 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3288 mLruProcesses.set(i - 1, tmp);
3292 // A gap, we can stop here.
3297 // Process has activities, put it at the very tipsy-top.
3298 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3299 mLruProcesses.add(app);
3301 nextIndex = mLruProcessServiceStart;
3302 } else if (hasService) {
3303 // Process has services, put it at the top of the service list.
3304 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3305 mLruProcesses.add(mLruProcessActivityStart, app);
3306 nextIndex = mLruProcessServiceStart;
3307 mLruProcessActivityStart++;
3309 // Process not otherwise of interest, it goes to the top of the non-service area.
3310 int index = mLruProcessServiceStart;
3311 if (client != null) {
3312 // If there is a client, don't allow the process to be moved up higher
3313 // in the list than that client.
3314 int clientIndex = mLruProcesses.lastIndexOf(client);
3315 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3316 + " when updating " + app);
3317 if (clientIndex <= lrui) {
3318 // Don't allow the client index restriction to push it down farther in the
3319 // list than it already is.
3322 if (clientIndex >= 0 && index > clientIndex) {
3323 index = clientIndex;
3326 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3327 mLruProcesses.add(index, app);
3328 nextIndex = index-1;
3329 mLruProcessActivityStart++;
3330 mLruProcessServiceStart++;
3333 // If the app is currently using a content provider or service,
3334 // bump those processes as well.
3335 for (int j=app.connections.size()-1; j>=0; j--) {
3336 ConnectionRecord cr = app.connections.valueAt(j);
3337 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3338 && cr.binding.service.app != null
3339 && cr.binding.service.app.lruSeq != mLruSeq
3340 && !cr.binding.service.app.persistent) {
3341 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3342 "service connection", cr, app);
3345 for (int j=app.conProviders.size()-1; j>=0; j--) {
3346 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3347 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3348 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3349 "provider reference", cpr, app);
3354 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3355 if (uid == Process.SYSTEM_UID) {
3356 // The system gets to run in any process. If there are multiple
3357 // processes with the same uid, just pick the first (this
3358 // should never happen).
3359 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3360 if (procs == null) return null;
3361 final int procCount = procs.size();
3362 for (int i = 0; i < procCount; i++) {
3363 final int procUid = procs.keyAt(i);
3364 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3365 // Don't use an app process or different user process for system component.
3368 return procs.valueAt(i);
3371 ProcessRecord proc = mProcessNames.get(processName, uid);
3372 if (false && proc != null && !keepIfLarge
3373 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3374 && proc.lastCachedPss >= 4000) {
3375 // Turn this condition on to cause killing to happen regularly, for testing.
3376 if (proc.baseProcessTracker != null) {
3377 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3379 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3380 } else if (proc != null && !keepIfLarge
3381 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3382 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3383 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3384 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3385 if (proc.baseProcessTracker != null) {
3386 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3388 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3394 void notifyPackageUse(String packageName, int reason) {
3395 IPackageManager pm = AppGlobals.getPackageManager();
3397 pm.notifyPackageUse(packageName, reason);
3398 } catch (RemoteException e) {
3402 boolean isNextTransitionForward() {
3403 int transit = mWindowManager.getPendingAppTransition();
3404 return transit == TRANSIT_ACTIVITY_OPEN
3405 || transit == TRANSIT_TASK_OPEN
3406 || transit == TRANSIT_TASK_TO_FRONT;
3409 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3410 String processName, String abiOverride, int uid, Runnable crashHandler) {
3411 synchronized(this) {
3412 ApplicationInfo info = new ApplicationInfo();
3413 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3414 // For isolated processes, the former contains the parent's uid and the latter the
3415 // actual uid of the isolated process.
3416 // In the special case introduced by this method (which is, starting an isolated
3417 // process directly from the SystemServer without an actual parent app process) the
3418 // closest thing to a parent's uid is SYSTEM_UID.
3419 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3420 // the |isolated| logic in the ProcessRecord constructor.
3421 info.uid = Process.SYSTEM_UID;
3422 info.processName = processName;
3423 info.className = entryPoint;
3424 info.packageName = "android";
3425 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3426 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3427 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3428 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3430 return proc != null ? proc.pid : 0;
3434 final ProcessRecord startProcessLocked(String processName,
3435 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3436 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3437 boolean isolated, boolean keepIfLarge) {
3438 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3439 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3440 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3441 null /* crashHandler */);
3444 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3445 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3446 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3447 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3448 long startTime = SystemClock.elapsedRealtime();
3451 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3452 checkTime(startTime, "startProcess: after getProcessRecord");
3454 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3455 // If we are in the background, then check to see if this process
3456 // is bad. If so, we will just silently fail.
3457 if (mAppErrors.isBadProcessLocked(info)) {
3458 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3459 + "/" + info.processName);
3463 // When the user is explicitly starting a process, then clear its
3464 // crash count so that we won't make it bad until they see at
3465 // least one crash dialog again, and make the process good again
3466 // if it had been bad.
3467 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3468 + "/" + info.processName);
3469 mAppErrors.resetProcessCrashTimeLocked(info);
3470 if (mAppErrors.isBadProcessLocked(info)) {
3471 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3472 UserHandle.getUserId(info.uid), info.uid,
3474 mAppErrors.clearBadProcessLocked(info);
3481 // If this is an isolated process, it can't re-use an existing process.
3485 // app launch boost for big.little configurations
3486 // use cpusets to migrate freshly launched tasks to big cores
3487 synchronized(ActivityManagerService.this) {
3488 nativeMigrateToBoost();
3490 mBoostStartTime = SystemClock.uptimeMillis();
3491 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3492 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3495 // We don't have to do anything more if:
3496 // (1) There is an existing application record; and
3497 // (2) The caller doesn't think it is dead, OR there is no thread
3498 // object attached to it so we know it couldn't have crashed; and
3499 // (3) There is a pid assigned to it, so it is either starting or
3501 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3502 + " app=" + app + " knownToBeDead=" + knownToBeDead
3503 + " thread=" + (app != null ? app.thread : null)
3504 + " pid=" + (app != null ? app.pid : -1));
3505 if (app != null && app.pid > 0) {
3506 if (!knownToBeDead || app.thread == null) {
3507 // We already have the app running, or are waiting for it to
3508 // come up (we have a pid but not yet its thread), so keep it.
3509 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3510 // If this is a new package in the process, add the package to the list
3511 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3512 checkTime(startTime, "startProcess: done, added package to proc");
3516 // An application record is attached to a previous process,
3518 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3519 checkTime(startTime, "startProcess: bad proc running, killing");
3520 killProcessGroup(app.uid, app.pid);
3521 handleAppDiedLocked(app, true, true);
3522 checkTime(startTime, "startProcess: done killing old proc");
3525 String hostingNameStr = hostingName != null
3526 ? hostingName.flattenToShortString() : null;
3529 checkTime(startTime, "startProcess: creating new process record");
3530 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3532 Slog.w(TAG, "Failed making new process record for "
3533 + processName + "/" + info.uid + " isolated=" + isolated);
3536 app.crashHandler = crashHandler;
3537 checkTime(startTime, "startProcess: done creating new process record");
3539 // If this is a new package in the process, add the package to the list
3540 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3541 checkTime(startTime, "startProcess: added package to existing proc");
3544 // If the system is not ready yet, then hold off on starting this
3545 // process until it is.
3546 if (!mProcessesReady
3547 && !isAllowedWhileBooting(info)
3548 && !allowWhileBooting) {
3549 if (!mProcessesOnHold.contains(app)) {
3550 mProcessesOnHold.add(app);
3552 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3553 "System not ready, putting on hold: " + app);
3554 checkTime(startTime, "startProcess: returning with proc on hold");
3558 checkTime(startTime, "startProcess: stepping in to startProcess");
3560 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3561 checkTime(startTime, "startProcess: done starting proc!");
3562 return (app.pid != 0) ? app : null;
3565 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3566 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3569 private final void startProcessLocked(ProcessRecord app,
3570 String hostingType, String hostingNameStr) {
3571 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3572 null /* entryPoint */, null /* entryPointArgs */);
3575 private final void startProcessLocked(ProcessRecord app, String hostingType,
3576 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3577 long startTime = SystemClock.elapsedRealtime();
3578 if (app.pid > 0 && app.pid != MY_PID) {
3579 checkTime(startTime, "startProcess: removing from pids map");
3580 synchronized (mPidsSelfLocked) {
3581 mPidsSelfLocked.remove(app.pid);
3582 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3584 checkTime(startTime, "startProcess: done removing from pids map");
3588 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3589 "startProcessLocked removing on hold: " + app);
3590 mProcessesOnHold.remove(app);
3592 checkTime(startTime, "startProcess: starting to update cpu stats");
3594 checkTime(startTime, "startProcess: done updating cpu stats");
3598 final int userId = UserHandle.getUserId(app.uid);
3599 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3600 } catch (RemoteException e) {
3601 throw e.rethrowAsRuntimeException();
3606 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3607 if (!app.isolated) {
3608 int[] permGids = null;
3610 checkTime(startTime, "startProcess: getting gids from package manager");
3611 final IPackageManager pm = AppGlobals.getPackageManager();
3612 permGids = pm.getPackageGids(app.info.packageName,
3613 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3614 MountServiceInternal mountServiceInternal = LocalServices.getService(
3615 MountServiceInternal.class);
3616 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3617 app.info.packageName);
3618 } catch (RemoteException e) {
3619 throw e.rethrowAsRuntimeException();
3623 * Add shared application and profile GIDs so applications can share some
3624 * resources like shared libraries and access user-wide resources
3626 if (ArrayUtils.isEmpty(permGids)) {
3629 gids = new int[permGids.length + 2];
3630 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3632 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3633 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3635 checkTime(startTime, "startProcess: building args");
3636 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3637 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3638 && mTopComponent != null
3639 && app.processName.equals(mTopComponent.getPackageName())) {
3642 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3643 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3648 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3649 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3650 // Also turn on CheckJNI for debuggable apps. It's quite
3651 // awkward to turn on otherwise.
3652 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3654 // Run the app in safe mode if its manifest requests so or the
3655 // system is booted in safe mode.
3656 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3657 mSafeMode == true) {
3658 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3660 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3661 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3663 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3664 if ("true".equals(genDebugInfoProperty)) {
3665 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3667 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3668 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3670 if ("1".equals(SystemProperties.get("debug.assert"))) {
3671 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3673 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3674 // Enable all debug flags required by the native debugger.
3675 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3676 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3677 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3678 mNativeDebuggingApp = null;
3681 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3682 if (requiredAbi == null) {
3683 requiredAbi = Build.SUPPORTED_ABIS[0];
3686 String instructionSet = null;
3687 if (app.info.primaryCpuAbi != null) {
3688 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3692 app.requiredAbi = requiredAbi;
3693 app.instructionSet = instructionSet;
3695 // Start the process. It will either succeed and return a result containing
3696 // the PID of the new process, or else throw a RuntimeException.
3697 boolean isActivityProcess = (entryPoint == null);
3698 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3699 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3701 checkTime(startTime, "startProcess: asking zygote to start proc");
3702 Process.ProcessStartResult startResult = Process.start(entryPoint,
3703 app.processName, uid, uid, gids, debugFlags, mountExternal,
3704 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3705 app.info.dataDir, entryPointArgs);
3706 checkTime(startTime, "startProcess: returned from zygote!");
3707 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3710 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3712 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3713 checkTime(startTime, "startProcess: done updating battery stats");
3715 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3716 UserHandle.getUserId(uid), startResult.pid, uid,
3717 app.processName, hostingType,
3718 hostingNameStr != null ? hostingNameStr : "");
3721 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3722 app.info.seinfo, app.info.sourceDir, startResult.pid);
3723 } catch (RemoteException ex) {
3727 if (app.persistent) {
3728 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3731 checkTime(startTime, "startProcess: building log message");
3732 StringBuilder buf = mStringBuilder;
3734 buf.append("Start proc ");
3735 buf.append(startResult.pid);
3737 buf.append(app.processName);
3739 UserHandle.formatUid(buf, uid);
3740 if (!isActivityProcess) {
3742 buf.append(entryPoint);
3745 buf.append(" for ");
3746 buf.append(hostingType);
3747 if (hostingNameStr != null) {
3749 buf.append(hostingNameStr);
3751 Slog.i(TAG, buf.toString());
3752 app.setPid(startResult.pid);
3753 app.usingWrapper = startResult.usingWrapper;
3754 app.removed = false;
3756 app.killedByAm = false;
3757 checkTime(startTime, "startProcess: starting to update pids map");
3758 synchronized (mPidsSelfLocked) {
3759 this.mPidsSelfLocked.put(startResult.pid, app);
3760 if (isActivityProcess) {
3761 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3763 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3764 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3767 checkTime(startTime, "startProcess: done updating pids map");
3768 } catch (RuntimeException e) {
3769 Slog.e(TAG, "Failure starting process " + app.processName, e);
3771 // Something went very wrong while trying to start this process; one
3772 // common case is when the package is frozen due to an active
3773 // upgrade. To recover, clean up any active bookkeeping related to
3774 // starting this process. (We already invoked this method once when
3775 // the package was initially frozen through KILL_APPLICATION_MSG, so
3776 // it doesn't hurt to use it again.)
3777 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3778 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3782 void updateUsageStats(ActivityRecord component, boolean resumed) {
3783 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3784 "updateUsageStats: comp=" + component + "res=" + resumed);
3785 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3787 if (mUsageStatsService != null) {
3788 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3789 UsageEvents.Event.MOVE_TO_FOREGROUND);
3791 synchronized (stats) {
3792 stats.noteActivityResumedLocked(component.app.uid);
3795 if (mUsageStatsService != null) {
3796 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3797 UsageEvents.Event.MOVE_TO_BACKGROUND);
3799 synchronized (stats) {
3800 stats.noteActivityPausedLocked(component.app.uid);
3805 Intent getHomeIntent() {
3806 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3807 intent.setComponent(mTopComponent);
3808 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3809 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3810 intent.addCategory(Intent.CATEGORY_HOME);
3815 boolean startHomeActivityLocked(int userId, String reason) {
3816 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3817 && mTopAction == null) {
3818 // We are running in factory test mode, but unable to find
3819 // the factory test app, so just sit around displaying the
3820 // error message and don't try to start anything.
3823 Intent intent = getHomeIntent();
3824 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3825 if (aInfo != null) {
3826 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3827 // Don't do this if the home app is currently being
3829 aInfo = new ActivityInfo(aInfo);
3830 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3831 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3832 aInfo.applicationInfo.uid, true);
3833 if (app == null || app.instrumentationClass == null) {
3834 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3835 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3838 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3844 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3845 ActivityInfo ai = null;
3846 ComponentName comp = intent.getComponent();
3850 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3852 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3854 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3858 ai = info.activityInfo;
3861 } catch (RemoteException e) {
3869 * Starts the "new version setup screen" if appropriate.
3871 void startSetupActivityLocked() {
3872 // Only do this once per boot.
3873 if (mCheckedForSetup) {
3877 // We will show this screen if the current one is a different
3878 // version than the last one shown, and we are not running in
3879 // low-level factory test mode.
3880 final ContentResolver resolver = mContext.getContentResolver();
3881 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3882 Settings.Global.getInt(resolver,
3883 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3884 mCheckedForSetup = true;
3886 // See if we should be showing the platform update setup UI.
3887 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3888 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3889 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3890 if (!ris.isEmpty()) {
3891 final ResolveInfo ri = ris.get(0);
3892 String vers = ri.activityInfo.metaData != null
3893 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3895 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3896 vers = ri.activityInfo.applicationInfo.metaData.getString(
3897 Intent.METADATA_SETUP_VERSION);
3899 String lastVers = Settings.Secure.getString(
3900 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3901 if (vers != null && !vers.equals(lastVers)) {
3902 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3903 intent.setComponent(new ComponentName(
3904 ri.activityInfo.packageName, ri.activityInfo.name));
3905 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3906 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3907 null, 0, 0, 0, null, false, false, null, null, null);
3913 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3914 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3917 void enforceNotIsolatedCaller(String caller) {
3918 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3919 throw new SecurityException("Isolated process not allowed to call " + caller);
3923 void enforceShellRestriction(String restriction, int userHandle) {
3924 if (Binder.getCallingUid() == Process.SHELL_UID) {
3925 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3926 throw new SecurityException("Shell does not have permission to access user "
3933 public int getFrontActivityScreenCompatMode() {
3934 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3935 synchronized (this) {
3936 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3941 public void setFrontActivityScreenCompatMode(int mode) {
3942 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3943 "setFrontActivityScreenCompatMode");
3944 synchronized (this) {
3945 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3950 public int getPackageScreenCompatMode(String packageName) {
3951 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3952 synchronized (this) {
3953 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3958 public void setPackageScreenCompatMode(String packageName, int mode) {
3959 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3960 "setPackageScreenCompatMode");
3961 synchronized (this) {
3962 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3967 public boolean getPackageAskScreenCompat(String packageName) {
3968 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3969 synchronized (this) {
3970 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3975 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3976 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3977 "setPackageAskScreenCompat");
3978 synchronized (this) {
3979 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3983 private boolean hasUsageStatsPermission(String callingPackage) {
3984 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3985 Binder.getCallingUid(), callingPackage);
3986 if (mode == AppOpsManager.MODE_DEFAULT) {
3987 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3988 == PackageManager.PERMISSION_GRANTED;
3990 return mode == AppOpsManager.MODE_ALLOWED;
3994 public int getPackageProcessState(String packageName, String callingPackage) {
3995 if (!hasUsageStatsPermission(callingPackage)) {
3996 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3997 "getPackageProcessState");
4000 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4001 synchronized (this) {
4002 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4003 final ProcessRecord proc = mLruProcesses.get(i);
4004 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4005 || procState > proc.setProcState) {
4006 boolean found = false;
4007 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4008 if (proc.pkgList.keyAt(j).equals(packageName)) {
4009 procState = proc.setProcState;
4013 if (proc.pkgDeps != null && !found) {
4014 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4015 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4016 procState = proc.setProcState;
4028 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4029 synchronized (this) {
4030 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4034 if (app.trimMemoryLevel < level && app.thread != null &&
4035 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4036 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4038 app.thread.scheduleTrimMemory(level);
4039 app.trimMemoryLevel = level;
4041 } catch (RemoteException e) {
4042 // Fallthrough to failure case.
4049 private void dispatchProcessesChanged() {
4051 synchronized (this) {
4052 N = mPendingProcessChanges.size();
4053 if (mActiveProcessChanges.length < N) {
4054 mActiveProcessChanges = new ProcessChangeItem[N];
4056 mPendingProcessChanges.toArray(mActiveProcessChanges);
4057 mPendingProcessChanges.clear();
4058 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4059 "*** Delivering " + N + " process changes");
4062 int i = mProcessObservers.beginBroadcast();
4065 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4066 if (observer != null) {
4068 for (int j=0; j<N; j++) {
4069 ProcessChangeItem item = mActiveProcessChanges[j];
4070 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4071 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4072 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4073 + item.uid + ": " + item.foregroundActivities);
4074 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4075 item.foregroundActivities);
4077 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4078 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4079 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4080 + ": " + item.processState);
4081 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4084 } catch (RemoteException e) {
4088 mProcessObservers.finishBroadcast();
4090 synchronized (this) {
4091 for (int j=0; j<N; j++) {
4092 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4097 private void dispatchProcessDied(int pid, int uid) {
4098 int i = mProcessObservers.beginBroadcast();
4101 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4102 if (observer != null) {
4104 observer.onProcessDied(pid, uid);
4105 } catch (RemoteException e) {
4109 mProcessObservers.finishBroadcast();
4112 private void dispatchUidsChanged() {
4114 synchronized (this) {
4115 N = mPendingUidChanges.size();
4116 if (mActiveUidChanges.length < N) {
4117 mActiveUidChanges = new UidRecord.ChangeItem[N];
4119 for (int i=0; i<N; i++) {
4120 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4121 mActiveUidChanges[i] = change;
4122 if (change.uidRecord != null) {
4123 change.uidRecord.pendingChange = null;
4124 change.uidRecord = null;
4127 mPendingUidChanges.clear();
4128 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4129 "*** Delivering " + N + " uid changes");
4132 if (mLocalPowerManager != null) {
4133 for (int j=0; j<N; j++) {
4134 UidRecord.ChangeItem item = mActiveUidChanges[j];
4135 if (item.change == UidRecord.CHANGE_GONE
4136 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4137 mLocalPowerManager.uidGone(item.uid);
4139 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4144 int i = mUidObservers.beginBroadcast();
4147 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4148 final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4149 if (observer != null) {
4151 for (int j=0; j<N; j++) {
4152 UidRecord.ChangeItem item = mActiveUidChanges[j];
4153 final int change = item.change;
4154 UidRecord validateUid = null;
4155 if (VALIDATE_UID_STATES && i == 0) {
4156 validateUid = mValidateUids.get(item.uid);
4157 if (validateUid == null && change != UidRecord.CHANGE_GONE
4158 && change != UidRecord.CHANGE_GONE_IDLE) {
4159 validateUid = new UidRecord(item.uid);
4160 mValidateUids.put(item.uid, validateUid);
4163 if (change == UidRecord.CHANGE_IDLE
4164 || change == UidRecord.CHANGE_GONE_IDLE) {
4165 if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4166 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4167 "UID idle uid=" + item.uid);
4168 observer.onUidIdle(item.uid);
4170 if (VALIDATE_UID_STATES && i == 0) {
4171 if (validateUid != null) {
4172 validateUid.idle = true;
4175 } else if (change == UidRecord.CHANGE_ACTIVE) {
4176 if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4177 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4178 "UID active uid=" + item.uid);
4179 observer.onUidActive(item.uid);
4181 if (VALIDATE_UID_STATES && i == 0) {
4182 validateUid.idle = false;
4185 if (change == UidRecord.CHANGE_GONE
4186 || change == UidRecord.CHANGE_GONE_IDLE) {
4187 if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4188 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4189 "UID gone uid=" + item.uid);
4190 observer.onUidGone(item.uid);
4192 if (VALIDATE_UID_STATES && i == 0) {
4193 if (validateUid != null) {
4194 mValidateUids.remove(item.uid);
4198 if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4199 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4200 "UID CHANGED uid=" + item.uid
4201 + ": " + item.processState);
4202 observer.onUidStateChanged(item.uid, item.processState);
4204 if (VALIDATE_UID_STATES && i == 0) {
4205 validateUid.curProcState = validateUid.setProcState
4206 = item.processState;
4210 } catch (RemoteException e) {
4214 mUidObservers.finishBroadcast();
4216 synchronized (this) {
4217 for (int j=0; j<N; j++) {
4218 mAvailUidChanges.add(mActiveUidChanges[j]);
4224 public final int startActivity(IApplicationThread caller, String callingPackage,
4225 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4226 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4227 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4228 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4229 UserHandle.getCallingUserId());
4232 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4233 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4234 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4235 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4236 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4238 // TODO: Switch to user app stacks here.
4239 String mimeType = intent.getType();
4240 final Uri data = intent.getData();
4241 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4242 mimeType = getProviderMimeType(data, userId);
4244 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4246 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4247 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4248 null, 0, 0, null, null, null, null, false, userId, container, null);
4252 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4253 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4254 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4255 enforceNotIsolatedCaller("startActivity");
4256 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4257 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4258 // TODO: Switch to user app stacks here.
4259 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4260 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4261 profilerInfo, null, null, bOptions, false, userId, null, null);
4265 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4266 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4267 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4270 // This is very dangerous -- it allows you to perform a start activity (including
4271 // permission grants) as any app that may launch one of your own activities. So
4272 // we will only allow this to be done from activities that are part of the core framework,
4273 // and then only when they are running as the system.
4274 final ActivityRecord sourceRecord;
4275 final int targetUid;
4276 final String targetPackage;
4277 synchronized (this) {
4278 if (resultTo == null) {
4279 throw new SecurityException("Must be called from an activity");
4281 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4282 if (sourceRecord == null) {
4283 throw new SecurityException("Called with bad activity token: " + resultTo);
4285 if (!sourceRecord.info.packageName.equals("android")) {
4286 throw new SecurityException(
4287 "Must be called from an activity that is declared in the android package");
4289 if (sourceRecord.app == null) {
4290 throw new SecurityException("Called without a process attached to activity");
4292 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4293 // This is still okay, as long as this activity is running under the
4294 // uid of the original calling activity.
4295 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4296 throw new SecurityException(
4297 "Calling activity in uid " + sourceRecord.app.uid
4298 + " must be system uid or original calling uid "
4299 + sourceRecord.launchedFromUid);
4302 if (ignoreTargetSecurity) {
4303 if (intent.getComponent() == null) {
4304 throw new SecurityException(
4305 "Component must be specified with ignoreTargetSecurity");
4307 if (intent.getSelector() != null) {
4308 throw new SecurityException(
4309 "Selector not allowed with ignoreTargetSecurity");
4312 targetUid = sourceRecord.launchedFromUid;
4313 targetPackage = sourceRecord.launchedFromPackage;
4316 if (userId == UserHandle.USER_NULL) {
4317 userId = UserHandle.getUserId(sourceRecord.app.uid);
4320 // TODO: Switch to user app stacks here.
4322 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4323 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4324 null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4326 } catch (SecurityException e) {
4327 // XXX need to figure out how to propagate to original app.
4328 // A SecurityException here is generally actually a fault of the original
4329 // calling activity (such as a fairly granting permissions), so propagate it
4332 StringBuilder msg = new StringBuilder();
4333 msg.append("While launching");
4334 msg.append(intent.toString());
4336 msg.append(e.getMessage());
4343 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4344 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4345 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4346 enforceNotIsolatedCaller("startActivityAndWait");
4347 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4348 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4349 WaitResult res = new WaitResult();
4350 // TODO: Switch to user app stacks here.
4351 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4352 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4353 bOptions, false, userId, null, null);
4358 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4359 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4360 int startFlags, Configuration config, Bundle bOptions, int userId) {
4361 enforceNotIsolatedCaller("startActivityWithConfig");
4362 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4363 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4364 // TODO: Switch to user app stacks here.
4365 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4366 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4367 null, null, config, bOptions, false, userId, null, null);
4372 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4373 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4374 int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4375 throws TransactionTooLargeException {
4376 enforceNotIsolatedCaller("startActivityIntentSender");
4377 // Refuse possible leaked file descriptors
4378 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4379 throw new IllegalArgumentException("File descriptors passed in Intent");
4382 IIntentSender sender = intent.getTarget();
4383 if (!(sender instanceof PendingIntentRecord)) {
4384 throw new IllegalArgumentException("Bad PendingIntent object");
4387 PendingIntentRecord pir = (PendingIntentRecord)sender;
4389 synchronized (this) {
4390 // If this is coming from the currently resumed activity, it is
4391 // effectively saying that app switches are allowed at this point.
4392 final ActivityStack stack = getFocusedStack();
4393 if (stack.mResumedActivity != null &&
4394 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4395 mAppSwitchesAllowedTime = 0;
4398 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4399 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4404 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4405 Intent intent, String resolvedType, IVoiceInteractionSession session,
4406 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4407 Bundle bOptions, int userId) {
4408 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4409 != PackageManager.PERMISSION_GRANTED) {
4410 String msg = "Permission Denial: startVoiceActivity() from pid="
4411 + Binder.getCallingPid()
4412 + ", uid=" + Binder.getCallingUid()
4413 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4415 throw new SecurityException(msg);
4417 if (session == null || interactor == null) {
4418 throw new NullPointerException("null session or interactor");
4420 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4421 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4422 // TODO: Switch to user app stacks here.
4423 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4424 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4425 null, bOptions, false, userId, null, null);
4429 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4430 throws RemoteException {
4431 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4432 synchronized (this) {
4433 ActivityRecord activity = getFocusedStack().topActivity();
4434 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4435 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4437 if (mRunningVoice != null || activity.task.voiceSession != null
4438 || activity.voiceSession != null) {
4439 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4442 if (activity.pendingVoiceInteractionStart) {
4443 Slog.w(TAG, "Pending start of voice interaction already.");
4446 activity.pendingVoiceInteractionStart = true;
4448 LocalServices.getService(VoiceInteractionManagerInternal.class)
4449 .startLocalVoiceInteraction(callingActivity, options);
4453 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4454 LocalServices.getService(VoiceInteractionManagerInternal.class)
4455 .stopLocalVoiceInteraction(callingActivity);
4459 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4460 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4461 .supportsLocalVoiceInteraction();
4464 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4465 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4466 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4467 if (activityToCallback == null) return;
4468 activityToCallback.setVoiceSessionLocked(voiceSession);
4470 // Inform the activity
4472 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4474 long token = Binder.clearCallingIdentity();
4476 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4478 Binder.restoreCallingIdentity(token);
4480 // TODO: VI Should we cache the activity so that it's easier to find later
4481 // rather than scan through all the stacks and activities?
4482 } catch (RemoteException re) {
4483 activityToCallback.clearVoiceSessionLocked();
4484 // TODO: VI Should this terminate the voice session?
4489 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4490 synchronized (this) {
4491 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4493 mVoiceWakeLock.acquire();
4495 mVoiceWakeLock.release();
4502 public boolean startNextMatchingActivity(IBinder callingActivity,
4503 Intent intent, Bundle bOptions) {
4504 // Refuse possible leaked file descriptors
4505 if (intent != null && intent.hasFileDescriptors() == true) {
4506 throw new IllegalArgumentException("File descriptors passed in Intent");
4508 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4510 synchronized (this) {
4511 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4513 ActivityOptions.abort(options);
4516 if (r.app == null || r.app.thread == null) {
4517 // The caller is not running... d'oh!
4518 ActivityOptions.abort(options);
4521 intent = new Intent(intent);
4522 // The caller is not allowed to change the data.
4523 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4524 // And we are resetting to find the next component...
4525 intent.setComponent(null);
4527 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4529 ActivityInfo aInfo = null;
4531 List<ResolveInfo> resolves =
4532 AppGlobals.getPackageManager().queryIntentActivities(
4533 intent, r.resolvedType,
4534 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4535 UserHandle.getCallingUserId()).getList();
4537 // Look for the original activity in the list...
4538 final int N = resolves != null ? resolves.size() : 0;
4539 for (int i=0; i<N; i++) {
4540 ResolveInfo rInfo = resolves.get(i);
4541 if (rInfo.activityInfo.packageName.equals(r.packageName)
4542 && rInfo.activityInfo.name.equals(r.info.name)) {
4543 // We found the current one... the next matching is
4547 aInfo = resolves.get(i).activityInfo;
4550 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4551 + "/" + r.info.name);
4552 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4553 ? "null" : aInfo.packageName + "/" + aInfo.name));
4558 } catch (RemoteException e) {
4561 if (aInfo == null) {
4562 // Nobody who is next!
4563 ActivityOptions.abort(options);
4564 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4568 intent.setComponent(new ComponentName(
4569 aInfo.applicationInfo.packageName, aInfo.name));
4570 intent.setFlags(intent.getFlags()&~(
4571 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4572 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4573 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4574 Intent.FLAG_ACTIVITY_NEW_TASK));
4576 // Okay now we need to start the new activity, replacing the
4577 // currently running activity. This is a little tricky because
4578 // we want to start the new one as if the current one is finished,
4579 // but not finish the current one first so that there is no flicker.
4581 final boolean wasFinishing = r.finishing;
4584 // Propagate reply information over to the new activity.
4585 final ActivityRecord resultTo = r.resultTo;
4586 final String resultWho = r.resultWho;
4587 final int requestCode = r.requestCode;
4589 if (resultTo != null) {
4590 resultTo.removeResultsLocked(r, resultWho, requestCode);
4593 final long origId = Binder.clearCallingIdentity();
4594 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4595 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4596 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4597 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4598 false, false, null, null, null);
4599 Binder.restoreCallingIdentity(origId);
4601 r.finishing = wasFinishing;
4602 if (res != ActivityManager.START_SUCCESS) {
4610 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4611 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4612 String msg = "Permission Denial: startActivityFromRecents called without " +
4613 START_TASKS_FROM_RECENTS;
4615 throw new SecurityException(msg);
4617 final long origId = Binder.clearCallingIdentity();
4619 synchronized (this) {
4620 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4623 Binder.restoreCallingIdentity(origId);
4627 final int startActivityInPackage(int uid, String callingPackage,
4628 Intent intent, String resolvedType, IBinder resultTo,
4629 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4630 IActivityContainer container, TaskRecord inTask) {
4632 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4633 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4635 // TODO: Switch to user app stacks here.
4636 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4637 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4638 null, null, null, bOptions, false, userId, container, inTask);
4643 public final int startActivities(IApplicationThread caller, String callingPackage,
4644 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4646 enforceNotIsolatedCaller("startActivities");
4647 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4648 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4649 // TODO: Switch to user app stacks here.
4650 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4651 resolvedTypes, resultTo, bOptions, userId);
4655 final int startActivitiesInPackage(int uid, String callingPackage,
4656 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4657 Bundle bOptions, int userId) {
4659 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4660 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4661 // TODO: Switch to user app stacks here.
4662 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4663 resultTo, bOptions, userId);
4668 public void reportActivityFullyDrawn(IBinder token) {
4669 synchronized (this) {
4670 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4674 r.reportFullyDrawnLocked();
4679 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4680 synchronized (this) {
4681 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4685 TaskRecord task = r.task;
4686 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4687 // Fixed screen orientation isn't supported when activities aren't in full screen
4691 final long origId = Binder.clearCallingIdentity();
4692 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4693 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4694 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4695 if (config != null) {
4696 r.frozenBeforeDestroy = true;
4697 if (!updateConfigurationLocked(config, r, false)) {
4698 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4701 Binder.restoreCallingIdentity(origId);
4706 public int getRequestedOrientation(IBinder token) {
4707 synchronized (this) {
4708 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4710 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4712 return mWindowManager.getAppOrientation(r.appToken);
4717 * This is the internal entry point for handling Activity.finish().
4719 * @param token The Binder token referencing the Activity we want to finish.
4720 * @param resultCode Result code, if any, from this Activity.
4721 * @param resultData Result data (Intent), if any, from this Activity.
4722 * @param finishTask Whether to finish the task associated with this Activity.
4724 * @return Returns true if the activity successfully finished, or false if it is still running.
4727 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4729 // Refuse possible leaked file descriptors
4730 if (resultData != null && resultData.hasFileDescriptors() == true) {
4731 throw new IllegalArgumentException("File descriptors passed in Intent");
4734 synchronized(this) {
4735 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4739 // Keep track of the root activity of the task before we finish it
4740 TaskRecord tr = r.task;
4741 ActivityRecord rootR = tr.getRootActivity();
4742 if (rootR == null) {
4743 Slog.w(TAG, "Finishing task with all activities already finished");
4745 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4747 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4748 mStackSupervisor.isLastLockedTask(tr)) {
4749 Slog.i(TAG, "Not finishing task in lock task mode");
4750 mStackSupervisor.showLockTaskToast();
4753 if (mController != null) {
4754 // Find the first activity that is not finishing.
4755 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4757 // ask watcher if this is allowed
4758 boolean resumeOK = true;
4760 resumeOK = mController.activityResuming(next.packageName);
4761 } catch (RemoteException e) {
4763 Watchdog.getInstance().setActivityController(null);
4767 Slog.i(TAG, "Not finishing activity because controller resumed");
4772 final long origId = Binder.clearCallingIdentity();
4775 final boolean finishWithRootActivity =
4776 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4777 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4778 || (finishWithRootActivity && r == rootR)) {
4779 // If requested, remove the task that is associated to this activity only if it
4780 // was the root activity in the task. The result code and data is ignored
4781 // because we don't support returning them across task boundaries. Also, to
4782 // keep backwards compatibility we remove the task from recents when finishing
4783 // task with root activity.
4784 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4786 Slog.i(TAG, "Removing task failed to finish activity");
4789 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4790 resultData, "app-request", true);
4792 Slog.i(TAG, "Failed to finish by app-request");
4797 Binder.restoreCallingIdentity(origId);
4803 public final void finishHeavyWeightApp() {
4804 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4805 != PackageManager.PERMISSION_GRANTED) {
4806 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4807 + Binder.getCallingPid()
4808 + ", uid=" + Binder.getCallingUid()
4809 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4811 throw new SecurityException(msg);
4814 synchronized(this) {
4815 if (mHeavyWeightProcess == null) {
4819 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4820 for (int i = 0; i < activities.size(); i++) {
4821 ActivityRecord r = activities.get(i);
4822 if (!r.finishing && r.isInStackLocked()) {
4823 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4824 null, "finish-heavy", true);
4828 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4829 mHeavyWeightProcess.userId, 0));
4830 mHeavyWeightProcess = null;
4835 public void crashApplication(int uid, int initialPid, String packageName,
4837 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4838 != PackageManager.PERMISSION_GRANTED) {
4839 String msg = "Permission Denial: crashApplication() from pid="
4840 + Binder.getCallingPid()
4841 + ", uid=" + Binder.getCallingUid()
4842 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4844 throw new SecurityException(msg);
4847 synchronized(this) {
4848 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4853 public final void finishSubActivity(IBinder token, String resultWho,
4855 synchronized(this) {
4856 final long origId = Binder.clearCallingIdentity();
4857 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4859 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4861 Binder.restoreCallingIdentity(origId);
4866 public boolean finishActivityAffinity(IBinder token) {
4867 synchronized(this) {
4868 final long origId = Binder.clearCallingIdentity();
4870 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4875 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4877 final TaskRecord task = r.task;
4878 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4879 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4880 mStackSupervisor.showLockTaskToast();
4883 return task.stack.finishActivityAffinityLocked(r);
4885 Binder.restoreCallingIdentity(origId);
4891 public void finishVoiceTask(IVoiceInteractionSession session) {
4892 synchronized (this) {
4893 final long origId = Binder.clearCallingIdentity();
4895 // TODO: VI Consider treating local voice interactions and voice tasks
4897 mStackSupervisor.finishVoiceTask(session);
4899 Binder.restoreCallingIdentity(origId);
4906 public boolean releaseActivityInstance(IBinder token) {
4907 synchronized(this) {
4908 final long origId = Binder.clearCallingIdentity();
4910 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4914 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4916 Binder.restoreCallingIdentity(origId);
4922 public void releaseSomeActivities(IApplicationThread appInt) {
4923 synchronized(this) {
4924 final long origId = Binder.clearCallingIdentity();
4926 ProcessRecord app = getRecordForAppLocked(appInt);
4927 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4929 Binder.restoreCallingIdentity(origId);
4935 public boolean willActivityBeVisible(IBinder token) {
4936 synchronized(this) {
4937 ActivityStack stack = ActivityRecord.getStackLocked(token);
4938 if (stack != null) {
4939 return stack.willActivityBeVisibleLocked(token);
4946 public void overridePendingTransition(IBinder token, String packageName,
4947 int enterAnim, int exitAnim) {
4948 synchronized(this) {
4949 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4954 final long origId = Binder.clearCallingIdentity();
4956 if (self.state == ActivityState.RESUMED
4957 || self.state == ActivityState.PAUSING) {
4958 mWindowManager.overridePendingAppTransition(packageName,
4959 enterAnim, exitAnim, null);
4962 Binder.restoreCallingIdentity(origId);
4967 * Main function for removing an existing process from the activity manager
4968 * as a result of that process going away. Clears out all connections
4971 private final void handleAppDiedLocked(ProcessRecord app,
4972 boolean restarting, boolean allowRestart) {
4974 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4975 if (!kept && !restarting) {
4976 removeLruProcessLocked(app);
4978 ProcessList.remove(pid);
4982 if (mProfileProc == app) {
4983 clearProfilerLocked();
4986 // Remove this application's activities from active lists.
4987 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4989 app.activities.clear();
4991 if (app.instrumentationClass != null) {
4992 Slog.w(TAG, "Crash of app " + app.processName
4993 + " running instrumentation " + app.instrumentationClass);
4994 Bundle info = new Bundle();
4995 info.putString("shortMsg", "Process crashed.");
4996 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4999 if (!restarting && hasVisibleActivities
5000 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5001 // If there was nothing to resume, and we are not already restarting this process, but
5002 // there is a visible activity that is hosted by the process... then make sure all
5003 // visible activities are running, taking care of restarting this process.
5004 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5008 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5009 IBinder threadBinder = thread.asBinder();
5010 // Find the application record.
5011 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5012 ProcessRecord rec = mLruProcesses.get(i);
5013 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5020 final ProcessRecord getRecordForAppLocked(
5021 IApplicationThread thread) {
5022 if (thread == null) {
5026 int appIndex = getLRURecordIndexForAppLocked(thread);
5027 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5030 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5031 // If there are no longer any background processes running,
5032 // and the app that died was not running instrumentation,
5033 // then tell everyone we are now low on memory.
5034 boolean haveBg = false;
5035 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5036 ProcessRecord rec = mLruProcesses.get(i);
5037 if (rec.thread != null
5038 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5045 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5047 long now = SystemClock.uptimeMillis();
5048 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5051 mLastMemUsageReportTime = now;
5054 final ArrayList<ProcessMemInfo> memInfos
5055 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5056 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5057 long now = SystemClock.uptimeMillis();
5058 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5059 ProcessRecord rec = mLruProcesses.get(i);
5060 if (rec == dyingProc || rec.thread == null) {
5064 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5065 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5067 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5068 // The low memory report is overriding any current
5069 // state for a GC request. Make sure to do
5070 // heavy/important/visible/foreground processes first.
5071 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5072 rec.lastRequestedGc = 0;
5074 rec.lastRequestedGc = rec.lastLowMemory;
5076 rec.reportLowMemory = true;
5077 rec.lastLowMemory = now;
5078 mProcessesToGc.remove(rec);
5079 addProcessToGcListLocked(rec);
5083 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5084 mHandler.sendMessage(msg);
5086 scheduleAppGcsLocked();
5090 final void appDiedLocked(ProcessRecord app) {
5091 appDiedLocked(app, app.pid, app.thread, false);
5094 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5095 boolean fromBinderDied) {
5096 // First check if this ProcessRecord is actually active for the pid.
5097 synchronized (mPidsSelfLocked) {
5098 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5099 if (curProc != app) {
5100 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5105 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5106 synchronized (stats) {
5107 stats.noteProcessDiedLocked(app.info.uid, pid);
5111 if (!fromBinderDied) {
5112 Process.killProcessQuiet(pid);
5114 killProcessGroup(app.uid, pid);
5118 // Clean up already done if the process has been re-started.
5119 if (app.pid == pid && app.thread != null &&
5120 app.thread.asBinder() == thread.asBinder()) {
5121 boolean doLowMem = app.instrumentationClass == null;
5122 boolean doOomAdj = doLowMem;
5123 if (!app.killedByAm) {
5124 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5126 mAllowLowerMemLevel = true;
5128 // Note that we always want to do oom adj to update our state with the
5129 // new number of procs.
5130 mAllowLowerMemLevel = false;
5133 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5134 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5135 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5136 handleAppDiedLocked(app, false, true);
5139 updateOomAdjLocked();
5142 doLowMemReportIfNeededLocked(app);
5144 } else if (app.pid != pid) {
5145 // A new process has already been started.
5146 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5147 + ") has died and restarted (pid " + app.pid + ").");
5148 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5149 } else if (DEBUG_PROCESSES) {
5150 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5151 + thread.asBinder());
5156 * If a stack trace dump file is configured, dump process stack traces.
5157 * @param clearTraces causes the dump file to be erased prior to the new
5158 * traces being written, if true; when false, the new traces will be
5159 * appended to any existing file content.
5160 * @param firstPids of dalvik VM processes to dump stack traces for first
5161 * @param lastPids of dalvik VM processes to dump stack traces for last
5162 * @param nativeProcs optional list of native process names to dump stack crawls
5163 * @return file containing stack traces, or null if no dump file is configured
5165 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5166 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5167 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5168 if (tracesPath == null || tracesPath.length() == 0) {
5172 File tracesFile = new File(tracesPath);
5174 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5175 tracesFile.createNewFile();
5176 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5177 } catch (IOException e) {
5178 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5182 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5186 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5187 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5188 // Use a FileObserver to detect when traces finish writing.
5189 // The order of traces is considered important to maintain for legibility.
5190 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5192 public synchronized void onEvent(int event, String path) { notify(); }
5196 observer.startWatching();
5198 // First collect all of the stacks of the most important pids.
5199 if (firstPids != null) {
5201 int num = firstPids.size();
5202 for (int i = 0; i < num; i++) {
5203 synchronized (observer) {
5204 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5205 + firstPids.get(i));
5206 final long sime = SystemClock.elapsedRealtime();
5207 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5208 observer.wait(1000); // Wait for write-close, give up after 1 sec
5209 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5210 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5213 } catch (InterruptedException e) {
5218 // Next collect the stacks of the native pids
5219 if (nativeProcs != null) {
5220 int[] pids = Process.getPidsForCommands(nativeProcs);
5222 for (int pid : pids) {
5223 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5224 final long sime = SystemClock.elapsedRealtime();
5225 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5226 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5227 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5232 // Lastly, measure CPU usage.
5233 if (processCpuTracker != null) {
5234 processCpuTracker.init();
5236 processCpuTracker.update();
5238 synchronized (processCpuTracker) {
5239 processCpuTracker.wait(500); // measure over 1/2 second.
5241 } catch (InterruptedException e) {
5243 processCpuTracker.update();
5245 // We'll take the stack crawls of just the top apps using CPU.
5246 final int N = processCpuTracker.countWorkingStats();
5248 for (int i=0; i<N && numProcs<5; i++) {
5249 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5250 if (lastPids.indexOfKey(stats.pid) >= 0) {
5253 synchronized (observer) {
5254 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5256 final long stime = SystemClock.elapsedRealtime();
5257 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5258 observer.wait(1000); // Wait for write-close, give up after 1 sec
5259 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5260 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5262 } catch (InterruptedException e) {
5265 } else if (DEBUG_ANR) {
5266 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5272 observer.stopWatching();
5276 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5277 if (true || IS_USER_BUILD) {
5280 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5281 if (tracesPath == null || tracesPath.length() == 0) {
5285 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5286 StrictMode.allowThreadDiskWrites();
5288 final File tracesFile = new File(tracesPath);
5289 final File tracesDir = tracesFile.getParentFile();
5290 final File tracesTmp = new File(tracesDir, "__tmp__");
5292 if (tracesFile.exists()) {
5294 tracesFile.renameTo(tracesTmp);
5296 StringBuilder sb = new StringBuilder();
5297 Time tobj = new Time();
5298 tobj.set(System.currentTimeMillis());
5299 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5301 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5302 sb.append(" since ");
5304 FileOutputStream fos = new FileOutputStream(tracesFile);
5305 fos.write(sb.toString().getBytes());
5307 fos.write("\n*** No application process!".getBytes());
5310 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5311 } catch (IOException e) {
5312 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5317 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5318 firstPids.add(app.pid);
5319 dumpStackTraces(tracesPath, firstPids, null, null, null);
5322 File lastTracesFile = null;
5323 File curTracesFile = null;
5324 for (int i=9; i>=0; i--) {
5325 String name = String.format(Locale.US, "slow%02d.txt", i);
5326 curTracesFile = new File(tracesDir, name);
5327 if (curTracesFile.exists()) {
5328 if (lastTracesFile != null) {
5329 curTracesFile.renameTo(lastTracesFile);
5331 curTracesFile.delete();
5334 lastTracesFile = curTracesFile;
5336 tracesFile.renameTo(curTracesFile);
5337 if (tracesTmp.exists()) {
5338 tracesTmp.renameTo(tracesFile);
5341 StrictMode.setThreadPolicy(oldPolicy);
5345 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5346 if (!mLaunchWarningShown) {
5347 mLaunchWarningShown = true;
5348 mUiHandler.post(new Runnable() {
5351 synchronized (ActivityManagerService.this) {
5352 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5354 mUiHandler.postDelayed(new Runnable() {
5357 synchronized (ActivityManagerService.this) {
5359 mLaunchWarningShown = false;
5370 public boolean clearApplicationUserData(final String packageName,
5371 final IPackageDataObserver observer, int userId) {
5372 enforceNotIsolatedCaller("clearApplicationUserData");
5373 int uid = Binder.getCallingUid();
5374 int pid = Binder.getCallingPid();
5375 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5376 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5378 final DevicePolicyManagerInternal dpmi = LocalServices
5379 .getService(DevicePolicyManagerInternal.class);
5380 if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5381 throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5384 long callingId = Binder.clearCallingIdentity();
5386 IPackageManager pm = AppGlobals.getPackageManager();
5388 synchronized(this) {
5390 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5391 } catch (RemoteException e) {
5394 Slog.w(TAG, "Invalid packageName: " + packageName);
5395 if (observer != null) {
5397 observer.onRemoveCompleted(packageName, false);
5398 } catch (RemoteException e) {
5399 Slog.i(TAG, "Observer no longer exists.");
5404 if (uid == pkgUid || checkComponentPermission(
5405 android.Manifest.permission.CLEAR_APP_USER_DATA,
5407 == PackageManager.PERMISSION_GRANTED) {
5408 forceStopPackageLocked(packageName, pkgUid, "clear data");
5410 throw new SecurityException("PID " + pid + " does not have permission "
5411 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5412 + " of package " + packageName);
5415 // Remove all tasks match the cleared application package and user
5416 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5417 final TaskRecord tr = mRecentTasks.get(i);
5418 final String taskPackageName =
5419 tr.getBaseIntent().getComponent().getPackageName();
5420 if (tr.userId != userId) continue;
5421 if (!taskPackageName.equals(packageName)) continue;
5422 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5426 final int pkgUidF = pkgUid;
5427 final int userIdF = userId;
5428 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5430 public void onRemoveCompleted(String packageName, boolean succeeded)
5431 throws RemoteException {
5432 synchronized (ActivityManagerService.this) {
5433 finishForceStopPackageLocked(packageName, pkgUidF);
5436 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5437 Uri.fromParts("package", packageName, null));
5438 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5439 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5440 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5441 null, null, 0, null, null, null, null, false, false, userIdF);
5443 if (observer != null) {
5444 observer.onRemoveCompleted(packageName, succeeded);
5450 // Clear application user data
5451 pm.clearApplicationUserData(packageName, localObserver, userId);
5453 synchronized(this) {
5454 // Remove all permissions granted from/to this package
5455 removeUriPermissionsForPackageLocked(packageName, userId, true);
5458 // Remove all zen rules created by this package; revoke it's zen access.
5459 INotificationManager inm = NotificationManager.getService();
5460 inm.removeAutomaticZenRules(packageName);
5461 inm.setNotificationPolicyAccessGranted(packageName, false);
5463 } catch (RemoteException e) {
5466 Binder.restoreCallingIdentity(callingId);
5472 public void killBackgroundProcesses(final String packageName, int userId) {
5473 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5474 != PackageManager.PERMISSION_GRANTED &&
5475 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5476 != PackageManager.PERMISSION_GRANTED) {
5477 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5478 + Binder.getCallingPid()
5479 + ", uid=" + Binder.getCallingUid()
5480 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5482 throw new SecurityException(msg);
5485 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5486 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5487 long callingId = Binder.clearCallingIdentity();
5489 IPackageManager pm = AppGlobals.getPackageManager();
5490 synchronized(this) {
5493 appId = UserHandle.getAppId(
5494 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5495 } catch (RemoteException e) {
5498 Slog.w(TAG, "Invalid packageName: " + packageName);
5501 killPackageProcessesLocked(packageName, appId, userId,
5502 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5505 Binder.restoreCallingIdentity(callingId);
5510 public void killAllBackgroundProcesses() {
5511 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5512 != PackageManager.PERMISSION_GRANTED) {
5513 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5514 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5515 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5517 throw new SecurityException(msg);
5520 final long callingId = Binder.clearCallingIdentity();
5522 synchronized (this) {
5523 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5524 final int NP = mProcessNames.getMap().size();
5525 for (int ip = 0; ip < NP; ip++) {
5526 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5527 final int NA = apps.size();
5528 for (int ia = 0; ia < NA; ia++) {
5529 final ProcessRecord app = apps.valueAt(ia);
5530 if (app.persistent) {
5531 // We don't kill persistent processes.
5536 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5543 final int N = procs.size();
5544 for (int i = 0; i < N; i++) {
5545 removeProcessLocked(procs.get(i), false, true, "kill all background");
5548 mAllowLowerMemLevel = true;
5550 updateOomAdjLocked();
5551 doLowMemReportIfNeededLocked(null);
5554 Binder.restoreCallingIdentity(callingId);
5559 * Kills all background processes, except those matching any of the
5560 * specified properties.
5562 * @param minTargetSdk the target SDK version at or above which to preserve
5563 * processes, or {@code -1} to ignore the target SDK
5564 * @param maxProcState the process state at or below which to preserve
5565 * processes, or {@code -1} to ignore the process state
5567 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5568 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5569 != PackageManager.PERMISSION_GRANTED) {
5570 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5571 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5572 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5574 throw new SecurityException(msg);
5577 final long callingId = Binder.clearCallingIdentity();
5579 synchronized (this) {
5580 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5581 final int NP = mProcessNames.getMap().size();
5582 for (int ip = 0; ip < NP; ip++) {
5583 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5584 final int NA = apps.size();
5585 for (int ia = 0; ia < NA; ia++) {
5586 final ProcessRecord app = apps.valueAt(ia);
5589 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5590 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5597 final int N = procs.size();
5598 for (int i = 0; i < N; i++) {
5599 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5603 Binder.restoreCallingIdentity(callingId);
5608 public void forceStopPackage(final String packageName, int userId) {
5609 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5610 != PackageManager.PERMISSION_GRANTED) {
5611 String msg = "Permission Denial: forceStopPackage() from pid="
5612 + Binder.getCallingPid()
5613 + ", uid=" + Binder.getCallingUid()
5614 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5616 throw new SecurityException(msg);
5618 final int callingPid = Binder.getCallingPid();
5619 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5620 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5621 long callingId = Binder.clearCallingIdentity();
5623 IPackageManager pm = AppGlobals.getPackageManager();
5624 synchronized(this) {
5625 int[] users = userId == UserHandle.USER_ALL
5626 ? mUserController.getUsers() : new int[] { userId };
5627 for (int user : users) {
5630 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5632 } catch (RemoteException e) {
5635 Slog.w(TAG, "Invalid packageName: " + packageName);
5639 pm.setPackageStoppedState(packageName, true, user);
5640 } catch (RemoteException e) {
5641 } catch (IllegalArgumentException e) {
5642 Slog.w(TAG, "Failed trying to unstop package "
5643 + packageName + ": " + e);
5645 if (mUserController.isUserRunningLocked(user, 0)) {
5646 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5647 finishForceStopPackageLocked(packageName, pkgUid);
5652 Binder.restoreCallingIdentity(callingId);
5657 public void addPackageDependency(String packageName) {
5658 synchronized (this) {
5659 int callingPid = Binder.getCallingPid();
5660 if (callingPid == Process.myPid()) {
5665 synchronized (mPidsSelfLocked) {
5666 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5669 if (proc.pkgDeps == null) {
5670 proc.pkgDeps = new ArraySet<String>(1);
5672 proc.pkgDeps.add(packageName);
5678 * The pkg name and app id have to be specified.
5681 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5685 // Make sure the uid is valid.
5687 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5690 int callerUid = Binder.getCallingUid();
5691 // Only the system server can kill an application
5692 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5693 // Post an aysnc message to kill the application
5694 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5697 Bundle bundle = new Bundle();
5698 bundle.putString("pkg", pkg);
5699 bundle.putString("reason", reason);
5701 mHandler.sendMessage(msg);
5703 throw new SecurityException(callerUid + " cannot kill pkg: " +
5709 public void closeSystemDialogs(String reason) {
5710 enforceNotIsolatedCaller("closeSystemDialogs");
5712 final int pid = Binder.getCallingPid();
5713 final int uid = Binder.getCallingUid();
5714 final long origId = Binder.clearCallingIdentity();
5716 synchronized (this) {
5717 // Only allow this from foreground processes, so that background
5718 // applications can't abuse it to prevent system UI from being shown.
5719 if (uid >= Process.FIRST_APPLICATION_UID) {
5721 synchronized (mPidsSelfLocked) {
5722 proc = mPidsSelfLocked.get(pid);
5724 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5725 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5726 + " from background process " + proc);
5730 closeSystemDialogsLocked(reason);
5733 Binder.restoreCallingIdentity(origId);
5737 void closeSystemDialogsLocked(String reason) {
5738 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5739 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5740 | Intent.FLAG_RECEIVER_FOREGROUND);
5741 if (reason != null) {
5742 intent.putExtra("reason", reason);
5744 mWindowManager.closeSystemDialogs(reason);
5746 mStackSupervisor.closeSystemDialogsLocked();
5748 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5749 AppOpsManager.OP_NONE, null, false, false,
5750 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5754 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5755 enforceNotIsolatedCaller("getProcessMemoryInfo");
5756 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5757 for (int i=pids.length-1; i>=0; i--) {
5760 synchronized (this) {
5761 synchronized (mPidsSelfLocked) {
5762 proc = mPidsSelfLocked.get(pids[i]);
5763 oomAdj = proc != null ? proc.setAdj : 0;
5766 infos[i] = new Debug.MemoryInfo();
5767 Debug.getMemoryInfo(pids[i], infos[i]);
5769 synchronized (this) {
5770 if (proc.thread != null && proc.setAdj == oomAdj) {
5771 // Record this for posterity if the process has been stable.
5772 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5773 infos[i].getTotalUss(), false, proc.pkgList);
5782 public long[] getProcessPss(int[] pids) {
5783 enforceNotIsolatedCaller("getProcessPss");
5784 long[] pss = new long[pids.length];
5785 for (int i=pids.length-1; i>=0; i--) {
5788 synchronized (this) {
5789 synchronized (mPidsSelfLocked) {
5790 proc = mPidsSelfLocked.get(pids[i]);
5791 oomAdj = proc != null ? proc.setAdj : 0;
5794 long[] tmpUss = new long[1];
5795 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5797 synchronized (this) {
5798 if (proc.thread != null && proc.setAdj == oomAdj) {
5799 // Record this for posterity if the process has been stable.
5800 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5809 public void killApplicationProcess(String processName, int uid) {
5810 if (processName == null) {
5814 int callerUid = Binder.getCallingUid();
5815 // Only the system server can kill an application
5816 if (callerUid == Process.SYSTEM_UID) {
5817 synchronized (this) {
5818 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5819 if (app != null && app.thread != null) {
5821 app.thread.scheduleSuicide();
5822 } catch (RemoteException e) {
5823 // If the other end already died, then our work here is done.
5826 Slog.w(TAG, "Process/uid not found attempting kill of "
5827 + processName + " / " + uid);
5831 throw new SecurityException(callerUid + " cannot kill app process: " +
5836 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5837 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5838 false, true, false, false, UserHandle.getUserId(uid), reason);
5841 private void finishForceStopPackageLocked(final String packageName, int uid) {
5842 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5843 Uri.fromParts("package", packageName, null));
5844 if (!mProcessesReady) {
5845 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5846 | Intent.FLAG_RECEIVER_FOREGROUND);
5848 intent.putExtra(Intent.EXTRA_UID, uid);
5849 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5850 broadcastIntentLocked(null, null, intent,
5851 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5852 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5856 private final boolean killPackageProcessesLocked(String packageName, int appId,
5857 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5858 boolean doit, boolean evenPersistent, String reason) {
5859 ArrayList<ProcessRecord> procs = new ArrayList<>();
5861 // Remove all processes this package may have touched: all with the
5862 // same UID (except for the system or root user), and all whose name
5863 // matches the package name.
5864 final int NP = mProcessNames.getMap().size();
5865 for (int ip=0; ip<NP; ip++) {
5866 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5867 final int NA = apps.size();
5868 for (int ia=0; ia<NA; ia++) {
5869 ProcessRecord app = apps.valueAt(ia);
5870 if (app.persistent && !evenPersistent) {
5871 // we don't kill persistent processes
5881 // Skip process if it doesn't meet our oom adj requirement.
5882 if (app.setAdj < minOomAdj) {
5886 // If no package is specified, we call all processes under the
5888 if (packageName == null) {
5889 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5892 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5895 // Package has been specified, we want to hit all processes
5896 // that match it. We need to qualify this by the processes
5897 // that are running under the specified app and user ID.
5899 final boolean isDep = app.pkgDeps != null
5900 && app.pkgDeps.contains(packageName);
5901 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5904 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5907 if (!app.pkgList.containsKey(packageName) && !isDep) {
5912 // Process has passed all conditions, kill it!
5921 int N = procs.size();
5922 for (int i=0; i<N; i++) {
5923 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5925 updateOomAdjLocked();
5929 private void cleanupDisabledPackageComponentsLocked(
5930 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5932 Set<String> disabledClasses = null;
5933 boolean packageDisabled = false;
5934 IPackageManager pm = AppGlobals.getPackageManager();
5936 if (changedClasses == null) {
5937 // Nothing changed...
5941 // Determine enable/disable state of the package and its components.
5942 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5943 for (int i = changedClasses.length - 1; i >= 0; i--) {
5944 final String changedClass = changedClasses[i];
5946 if (changedClass.equals(packageName)) {
5948 // Entire package setting changed
5949 enabled = pm.getApplicationEnabledSetting(packageName,
5950 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5951 } catch (Exception e) {
5952 // No such package/component; probably racing with uninstall. In any
5953 // event it means we have nothing further to do here.
5956 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5957 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5958 if (packageDisabled) {
5959 // Entire package is disabled.
5960 // No need to continue to check component states.
5961 disabledClasses = null;
5966 enabled = pm.getComponentEnabledSetting(
5967 new ComponentName(packageName, changedClass),
5968 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5969 } catch (Exception e) {
5970 // As above, probably racing with uninstall.
5973 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5974 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5975 if (disabledClasses == null) {
5976 disabledClasses = new ArraySet<>(changedClasses.length);
5978 disabledClasses.add(changedClass);
5983 if (!packageDisabled && disabledClasses == null) {
5984 // Nothing to do here...
5988 // Clean-up disabled activities.
5989 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5990 packageName, disabledClasses, true, false, userId) && mBooted) {
5991 mStackSupervisor.resumeFocusedStackTopActivityLocked();
5992 mStackSupervisor.scheduleIdleLocked();
5995 // Clean-up disabled tasks
5996 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5998 // Clean-up disabled services.
5999 mServices.bringDownDisabledPackageServicesLocked(
6000 packageName, disabledClasses, userId, false, killProcess, true);
6002 // Clean-up disabled providers.
6003 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6004 mProviderMap.collectPackageProvidersLocked(
6005 packageName, disabledClasses, true, false, userId, providers);
6006 for (int i = providers.size() - 1; i >= 0; i--) {
6007 removeDyingProviderLocked(null, providers.get(i), true);
6010 // Clean-up disabled broadcast receivers.
6011 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6012 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6013 packageName, disabledClasses, userId, true);
6018 final boolean clearBroadcastQueueForUserLocked(int userId) {
6019 boolean didSomething = false;
6020 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6021 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6022 null, null, userId, true);
6024 return didSomething;
6027 final boolean forceStopPackageLocked(String packageName, int appId,
6028 boolean callerWillRestart, boolean purgeCache, boolean doit,
6029 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6032 if (userId == UserHandle.USER_ALL && packageName == null) {
6033 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6036 if (appId < 0 && packageName != null) {
6038 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6039 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
6040 } catch (RemoteException e) {
6045 if (packageName != null) {
6046 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6047 + " user=" + userId + ": " + reason);
6049 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6052 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6055 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6056 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6057 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6059 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6060 packageName, null, doit, evenPersistent, userId)) {
6064 didSomething = true;
6067 if (mServices.bringDownDisabledPackageServicesLocked(
6068 packageName, null, userId, evenPersistent, true, doit)) {
6072 didSomething = true;
6075 if (packageName == null) {
6076 // Remove all sticky broadcasts from this user.
6077 mStickyBroadcasts.remove(userId);
6080 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6081 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6082 userId, providers)) {
6086 didSomething = true;
6088 for (i = providers.size() - 1; i >= 0; i--) {
6089 removeDyingProviderLocked(null, providers.get(i), true);
6092 // Remove transient permissions granted from/to this package/user
6093 removeUriPermissionsForPackageLocked(packageName, userId, false);
6096 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6097 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6098 packageName, null, userId, doit);
6102 if (packageName == null || uninstalling) {
6103 // Remove pending intents. For now we only do this when force
6104 // stopping users, because we have some problems when doing this
6105 // for packages -- app widgets are not currently cleaned up for
6106 // such packages, so they can be left with bad pending intents.
6107 if (mIntentSenderRecords.size() > 0) {
6108 Iterator<WeakReference<PendingIntentRecord>> it
6109 = mIntentSenderRecords.values().iterator();
6110 while (it.hasNext()) {
6111 WeakReference<PendingIntentRecord> wpir = it.next();
6116 PendingIntentRecord pir = wpir.get();
6121 if (packageName == null) {
6122 // Stopping user, remove all objects for the user.
6123 if (pir.key.userId != userId) {
6124 // Not the same user, skip it.
6128 if (UserHandle.getAppId(pir.uid) != appId) {
6129 // Different app id, skip it.
6132 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6133 // Different user, skip it.
6136 if (!pir.key.packageName.equals(packageName)) {
6137 // Different package, skip it.
6144 didSomething = true;
6146 pir.canceled = true;
6147 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6148 pir.key.activity.pendingResults.remove(pir.ref);
6155 if (purgeCache && packageName != null) {
6156 AttributeCache ac = AttributeCache.instance();
6158 ac.removePackage(packageName);
6162 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6163 mStackSupervisor.scheduleIdleLocked();
6167 return didSomething;
6170 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6171 ProcessRecord old = mProcessNames.remove(name, uid);
6173 old.uidRecord.numProcs--;
6174 if (old.uidRecord.numProcs == 0) {
6175 // No more processes using this uid, tell clients it is gone.
6176 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6177 "No more processes in " + old.uidRecord);
6178 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6179 mActiveUids.remove(uid);
6180 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6182 old.uidRecord = null;
6184 mIsolatedProcesses.remove(uid);
6188 private final void addProcessNameLocked(ProcessRecord proc) {
6189 // We shouldn't already have a process under this name, but just in case we
6190 // need to clean up whatever may be there now.
6191 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6192 if (old == proc && proc.persistent) {
6193 // We are re-adding a persistent process. Whatevs! Just leave it there.
6194 Slog.w(TAG, "Re-adding persistent process " + proc);
6195 } else if (old != null) {
6196 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6198 UidRecord uidRec = mActiveUids.get(proc.uid);
6199 if (uidRec == null) {
6200 uidRec = new UidRecord(proc.uid);
6201 // This is the first appearance of the uid, report it now!
6202 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6203 "Creating new process uid: " + uidRec);
6204 mActiveUids.put(proc.uid, uidRec);
6205 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6206 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6208 proc.uidRecord = uidRec;
6210 mProcessNames.put(proc.processName, proc.uid, proc);
6211 if (proc.isolated) {
6212 mIsolatedProcesses.put(proc.uid, proc);
6216 boolean removeProcessLocked(ProcessRecord app,
6217 boolean callerWillRestart, boolean allowRestart, String reason) {
6218 final String name = app.processName;
6219 final int uid = app.uid;
6220 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6221 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6223 ProcessRecord old = mProcessNames.get(name, uid);
6225 // This process is no longer active, so nothing to do.
6226 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6229 removeProcessNameLocked(name, uid);
6230 if (mHeavyWeightProcess == app) {
6231 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6232 mHeavyWeightProcess.userId, 0));
6233 mHeavyWeightProcess = null;
6235 boolean needRestart = false;
6236 if (app.pid > 0 && app.pid != MY_PID) {
6238 synchronized (mPidsSelfLocked) {
6239 mPidsSelfLocked.remove(pid);
6240 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6242 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6244 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6246 boolean willRestart = false;
6247 if (app.persistent && !app.isolated) {
6248 if (!callerWillRestart) {
6254 app.kill(reason, true);
6255 handleAppDiedLocked(app, willRestart, allowRestart);
6257 removeLruProcessLocked(app);
6258 addAppLocked(app.info, false, null /* ABI override */);
6261 mRemovedProcesses.add(app);
6267 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6268 cleanupAppInLaunchingProvidersLocked(app, true);
6269 removeProcessLocked(app, false, true, "timeout publishing content providers");
6272 private final void processStartTimedOutLocked(ProcessRecord app) {
6273 final int pid = app.pid;
6274 boolean gone = false;
6275 synchronized (mPidsSelfLocked) {
6276 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6277 if (knownApp != null && knownApp.thread == null) {
6278 mPidsSelfLocked.remove(pid);
6284 Slog.w(TAG, "Process " + app + " failed to attach");
6285 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6286 pid, app.uid, app.processName);
6287 removeProcessNameLocked(app.processName, app.uid);
6288 if (mHeavyWeightProcess == app) {
6289 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6290 mHeavyWeightProcess.userId, 0));
6291 mHeavyWeightProcess = null;
6293 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6295 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6297 // Take care of any launching providers waiting for this process.
6298 cleanupAppInLaunchingProvidersLocked(app, true);
6299 // Take care of any services that are waiting for the process.
6300 mServices.processStartTimedOutLocked(app);
6301 app.kill("start timeout", true);
6302 removeLruProcessLocked(app);
6303 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6304 Slog.w(TAG, "Unattached app died before backup, skipping");
6306 IBackupManager bm = IBackupManager.Stub.asInterface(
6307 ServiceManager.getService(Context.BACKUP_SERVICE));
6308 bm.agentDisconnected(app.info.packageName);
6309 } catch (RemoteException e) {
6310 // Can't happen; the backup manager is local
6313 if (isPendingBroadcastProcessLocked(pid)) {
6314 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6315 skipPendingBroadcastLocked(pid);
6318 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6322 private final boolean attachApplicationLocked(IApplicationThread thread,
6325 // Find the application record that is being attached... either via
6326 // the pid if we are running in multiple processes, or just pull the
6327 // next app record if we are emulating process with anonymous threads.
6329 if (pid != MY_PID && pid >= 0) {
6330 synchronized (mPidsSelfLocked) {
6331 app = mPidsSelfLocked.get(pid);
6338 Slog.w(TAG, "No pending application record for pid " + pid
6339 + " (IApplicationThread " + thread + "); dropping process");
6340 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6341 if (pid > 0 && pid != MY_PID) {
6342 Process.killProcessQuiet(pid);
6343 //TODO: killProcessGroup(app.info.uid, pid);
6346 thread.scheduleExit();
6347 } catch (Exception e) {
6348 // Ignore exceptions.
6354 // If this application record is still attached to a previous
6355 // process, clean it up now.
6356 if (app.thread != null) {
6357 handleAppDiedLocked(app, true, true);
6360 // Tell the process all about itself.
6362 if (DEBUG_ALL) Slog.v(
6363 TAG, "Binding process pid " + pid + " to record " + app);
6365 final String processName = app.processName;
6367 AppDeathRecipient adr = new AppDeathRecipient(
6369 thread.asBinder().linkToDeath(adr, 0);
6370 app.deathRecipient = adr;
6371 } catch (RemoteException e) {
6372 app.resetPackageList(mProcessStats);
6373 startProcessLocked(app, "link fail", processName);
6377 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6379 app.makeActive(thread, mProcessStats);
6380 app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6381 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6382 app.forcingToForeground = null;
6383 updateProcessForegroundLocked(app, false, false);
6384 app.hasShownUi = false;
6385 app.debugging = false;
6387 app.killedByAm = false;
6389 // We carefully use the same state that PackageManager uses for
6390 // filtering, since we use this flag to decide if we need to install
6391 // providers when user is unlocked later
6392 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6394 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6396 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6397 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6399 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6400 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6402 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6406 Slog.i(TAG, "Launching preboot mode app: " + app);
6409 if (DEBUG_ALL) Slog.v(
6410 TAG, "New app record " + app
6411 + " thread=" + thread.asBinder() + " pid=" + pid);
6413 int testMode = IApplicationThread.DEBUG_OFF;
6414 if (mDebugApp != null && mDebugApp.equals(processName)) {
6415 testMode = mWaitForDebugger
6416 ? IApplicationThread.DEBUG_WAIT
6417 : IApplicationThread.DEBUG_ON;
6418 app.debugging = true;
6419 if (mDebugTransient) {
6420 mDebugApp = mOrigDebugApp;
6421 mWaitForDebugger = mOrigWaitForDebugger;
6424 String profileFile = app.instrumentationProfileFile;
6425 ParcelFileDescriptor profileFd = null;
6426 int samplingInterval = 0;
6427 boolean profileAutoStop = false;
6428 if (mProfileApp != null && mProfileApp.equals(processName)) {
6430 profileFile = mProfileFile;
6431 profileFd = mProfileFd;
6432 samplingInterval = mSamplingInterval;
6433 profileAutoStop = mAutoStopProfiler;
6435 boolean enableTrackAllocation = false;
6436 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6437 enableTrackAllocation = true;
6438 mTrackAllocationApp = null;
6441 // If the app is being launched for restore or full backup, set it up specially
6442 boolean isRestrictedBackupMode = false;
6443 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6444 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6445 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6446 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6447 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6450 if (app.instrumentationClass != null) {
6451 notifyPackageUse(app.instrumentationClass.getPackageName(),
6452 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6454 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6455 + processName + " with config " + mConfiguration);
6456 ApplicationInfo appInfo = app.instrumentationInfo != null
6457 ? app.instrumentationInfo : app.info;
6458 app.compat = compatibilityInfoForPackageLocked(appInfo);
6459 if (profileFd != null) {
6460 profileFd = profileFd.dup();
6462 ProfilerInfo profilerInfo = profileFile == null ? null
6463 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6464 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6465 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6466 app.instrumentationUiAutomationConnection, testMode,
6467 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6468 isRestrictedBackupMode || !normalMode, app.persistent,
6469 new Configuration(mConfiguration), app.compat,
6470 getCommonServicesLocked(app.isolated),
6471 mCoreSettingsObserver.getCoreSettingsLocked());
6472 updateLruProcessLocked(app, false, null);
6473 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6474 } catch (Exception e) {
6475 // todo: Yikes! What should we do? For now we will try to
6476 // start another process, but that could easily get us in
6477 // an infinite loop of restarting processes...
6478 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6480 app.resetPackageList(mProcessStats);
6481 app.unlinkDeathRecipient();
6482 startProcessLocked(app, "bind fail", processName);
6486 // Remove this record from the list of starting applications.
6487 mPersistentStartingProcesses.remove(app);
6488 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6489 "Attach application locked removing on hold: " + app);
6490 mProcessesOnHold.remove(app);
6492 boolean badApp = false;
6493 boolean didSomething = false;
6495 // See if the top visible activity is waiting to run in this process...
6498 if (mStackSupervisor.attachApplicationLocked(app)) {
6499 didSomething = true;
6501 } catch (Exception e) {
6502 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6507 // Find any services that should be running in this process...
6510 didSomething |= mServices.attachApplicationLocked(app, processName);
6511 } catch (Exception e) {
6512 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6517 // Check if a next-broadcast receiver is in this process...
6518 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6520 didSomething |= sendPendingBroadcastsLocked(app);
6521 } catch (Exception e) {
6522 // If the app died trying to launch the receiver we declare it 'bad'
6523 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6528 // Check whether the next backup agent is in this process...
6529 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6530 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6531 "New app is backup target, launching agent for " + app);
6532 notifyPackageUse(mBackupTarget.appInfo.packageName,
6533 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6535 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6536 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6537 mBackupTarget.backupMode);
6538 } catch (Exception e) {
6539 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6545 app.kill("error during init", true);
6546 handleAppDiedLocked(app, false, true);
6550 if (!didSomething) {
6551 updateOomAdjLocked();
6558 public final void attachApplication(IApplicationThread thread) {
6559 synchronized (this) {
6560 int callingPid = Binder.getCallingPid();
6561 final long origId = Binder.clearCallingIdentity();
6562 attachApplicationLocked(thread, callingPid);
6563 Binder.restoreCallingIdentity(origId);
6568 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6569 final long origId = Binder.clearCallingIdentity();
6570 synchronized (this) {
6571 ActivityStack stack = ActivityRecord.getStackLocked(token);
6572 if (stack != null) {
6574 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6575 if (stopProfiling) {
6576 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6579 } catch (IOException e) {
6581 clearProfilerLocked();
6586 Binder.restoreCallingIdentity(origId);
6589 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6590 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6591 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6594 void enableScreenAfterBoot() {
6595 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6596 SystemClock.uptimeMillis());
6597 mWindowManager.enableScreenAfterBoot();
6599 synchronized (this) {
6600 updateEventDispatchingLocked();
6605 public void showBootMessage(final CharSequence msg, final boolean always) {
6606 if (Binder.getCallingUid() != Process.myUid()) {
6607 // These days only the core system can call this, so apps can't get in
6608 // the way of what we show about running them.
6610 mWindowManager.showBootMessage(msg, always);
6614 public void keyguardWaitingForActivityDrawn() {
6615 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6616 final long token = Binder.clearCallingIdentity();
6618 synchronized (this) {
6619 if (DEBUG_LOCKSCREEN) logLockScreen("");
6620 mWindowManager.keyguardWaitingForActivityDrawn();
6621 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6622 mLockScreenShown = LOCK_SCREEN_LEAVING;
6623 updateSleepIfNeededLocked();
6627 Binder.restoreCallingIdentity(token);
6632 public void keyguardGoingAway(int flags) {
6633 enforceNotIsolatedCaller("keyguardGoingAway");
6634 final long token = Binder.clearCallingIdentity();
6636 synchronized (this) {
6637 if (DEBUG_LOCKSCREEN) logLockScreen("");
6638 mWindowManager.keyguardGoingAway(flags);
6639 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6640 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6641 updateSleepIfNeededLocked();
6643 // Some stack visibility might change (e.g. docked stack)
6644 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6645 applyVrModeIfNeededLocked(mFocusedActivity, true);
6649 Binder.restoreCallingIdentity(token);
6653 final void finishBooting() {
6654 synchronized (this) {
6655 if (!mBootAnimationComplete) {
6656 mCallFinishBooting = true;
6659 mCallFinishBooting = false;
6662 ArraySet<String> completedIsas = new ArraySet<String>();
6663 for (String abi : Build.SUPPORTED_ABIS) {
6664 Process.establishZygoteConnectionForAbi(abi);
6665 final String instructionSet = VMRuntime.getInstructionSet(abi);
6666 if (!completedIsas.contains(instructionSet)) {
6668 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6669 } catch (InstallerException e) {
6670 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6671 e.getMessage() +")");
6673 completedIsas.add(instructionSet);
6677 IntentFilter pkgFilter = new IntentFilter();
6678 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6679 pkgFilter.addDataScheme("package");
6680 mContext.registerReceiver(new BroadcastReceiver() {
6682 public void onReceive(Context context, Intent intent) {
6683 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6685 for (String pkg : pkgs) {
6686 synchronized (ActivityManagerService.this) {
6687 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6688 0, "query restart")) {
6689 setResultCode(Activity.RESULT_OK);
6698 IntentFilter dumpheapFilter = new IntentFilter();
6699 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6700 mContext.registerReceiver(new BroadcastReceiver() {
6702 public void onReceive(Context context, Intent intent) {
6703 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6704 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6706 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6711 // Let system services know.
6712 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6714 synchronized (this) {
6715 // Ensure that any processes we had put on hold are now started
6717 final int NP = mProcessesOnHold.size();
6719 ArrayList<ProcessRecord> procs =
6720 new ArrayList<ProcessRecord>(mProcessesOnHold);
6721 for (int ip=0; ip<NP; ip++) {
6722 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6724 startProcessLocked(procs.get(ip), "on-hold", null);
6728 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6729 // Start looking for apps that are abusing wake locks.
6730 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6731 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6732 // Tell anyone interested that we are done booting!
6733 SystemProperties.set("sys.boot_completed", "1");
6735 // And trigger dev.bootcomplete if we are not showing encryption progress
6736 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6737 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6738 SystemProperties.set("dev.bootcomplete", "1");
6740 mUserController.sendBootCompletedLocked(
6741 new IIntentReceiver.Stub() {
6743 public void performReceive(Intent intent, int resultCode,
6744 String data, Bundle extras, boolean ordered,
6745 boolean sticky, int sendingUser) {
6746 synchronized (ActivityManagerService.this) {
6747 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6752 scheduleStartProfilesLocked();
6758 public void bootAnimationComplete() {
6759 final boolean callFinishBooting;
6760 synchronized (this) {
6761 callFinishBooting = mCallFinishBooting;
6762 mBootAnimationComplete = true;
6764 if (callFinishBooting) {
6765 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6767 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6771 final void ensureBootCompleted() {
6773 boolean enableScreen;
6774 synchronized (this) {
6777 enableScreen = !mBooted;
6782 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6784 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6788 enableScreenAfterBoot();
6793 public final void activityResumed(IBinder token) {
6794 final long origId = Binder.clearCallingIdentity();
6795 synchronized(this) {
6796 ActivityStack stack = ActivityRecord.getStackLocked(token);
6797 if (stack != null) {
6798 stack.activityResumedLocked(token);
6801 Binder.restoreCallingIdentity(origId);
6805 public final void activityPaused(IBinder token) {
6806 final long origId = Binder.clearCallingIdentity();
6807 synchronized(this) {
6808 ActivityStack stack = ActivityRecord.getStackLocked(token);
6809 if (stack != null) {
6810 stack.activityPausedLocked(token, false);
6813 Binder.restoreCallingIdentity(origId);
6817 public final void activityStopped(IBinder token, Bundle icicle,
6818 PersistableBundle persistentState, CharSequence description) {
6819 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6821 // Refuse possible leaked file descriptors
6822 if (icicle != null && icicle.hasFileDescriptors()) {
6823 throw new IllegalArgumentException("File descriptors passed in Bundle");
6826 final long origId = Binder.clearCallingIdentity();
6828 synchronized (this) {
6829 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6831 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6837 Binder.restoreCallingIdentity(origId);
6841 public final void activityDestroyed(IBinder token) {
6842 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6843 synchronized (this) {
6844 ActivityStack stack = ActivityRecord.getStackLocked(token);
6845 if (stack != null) {
6846 stack.activityDestroyedLocked(token, "activityDestroyed");
6852 public final void activityRelaunched(IBinder token) {
6853 final long origId = Binder.clearCallingIdentity();
6854 synchronized (this) {
6855 mStackSupervisor.activityRelaunchedLocked(token);
6857 Binder.restoreCallingIdentity(origId);
6861 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6862 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6863 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6864 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6865 synchronized (this) {
6866 ActivityRecord record = ActivityRecord.isInStackLocked(token);
6867 if (record == null) {
6868 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6869 + "found for: " + token);
6871 record.setSizeConfigurations(horizontalSizeConfiguration,
6872 verticalSizeConfigurations, smallestSizeConfigurations);
6877 public final void backgroundResourcesReleased(IBinder token) {
6878 final long origId = Binder.clearCallingIdentity();
6880 synchronized (this) {
6881 ActivityStack stack = ActivityRecord.getStackLocked(token);
6882 if (stack != null) {
6883 stack.backgroundResourcesReleased();
6887 Binder.restoreCallingIdentity(origId);
6892 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6893 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6897 public final void notifyEnterAnimationComplete(IBinder token) {
6898 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6902 public String getCallingPackage(IBinder token) {
6903 synchronized (this) {
6904 ActivityRecord r = getCallingRecordLocked(token);
6905 return r != null ? r.info.packageName : null;
6910 public ComponentName getCallingActivity(IBinder token) {
6911 synchronized (this) {
6912 ActivityRecord r = getCallingRecordLocked(token);
6913 return r != null ? r.intent.getComponent() : null;
6917 private ActivityRecord getCallingRecordLocked(IBinder token) {
6918 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6926 public ComponentName getActivityClassForToken(IBinder token) {
6927 synchronized(this) {
6928 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6932 return r.intent.getComponent();
6937 public String getPackageForToken(IBinder token) {
6938 synchronized(this) {
6939 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6943 return r.packageName;
6948 public boolean isRootVoiceInteraction(IBinder token) {
6949 synchronized(this) {
6950 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6954 return r.rootVoiceInteraction;
6959 public IIntentSender getIntentSender(int type,
6960 String packageName, IBinder token, String resultWho,
6961 int requestCode, Intent[] intents, String[] resolvedTypes,
6962 int flags, Bundle bOptions, int userId) {
6963 enforceNotIsolatedCaller("getIntentSender");
6964 // Refuse possible leaked file descriptors
6965 if (intents != null) {
6966 if (intents.length < 1) {
6967 throw new IllegalArgumentException("Intents array length must be >= 1");
6969 for (int i=0; i<intents.length; i++) {
6970 Intent intent = intents[i];
6971 if (intent != null) {
6972 if (intent.hasFileDescriptors()) {
6973 throw new IllegalArgumentException("File descriptors passed in Intent");
6975 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6976 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6977 throw new IllegalArgumentException(
6978 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6980 intents[i] = new Intent(intent);
6983 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6984 throw new IllegalArgumentException(
6985 "Intent array length does not match resolvedTypes length");
6988 if (bOptions != null) {
6989 if (bOptions.hasFileDescriptors()) {
6990 throw new IllegalArgumentException("File descriptors passed in options");
6994 synchronized(this) {
6995 int callingUid = Binder.getCallingUid();
6996 int origUserId = userId;
6997 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6998 type == ActivityManager.INTENT_SENDER_BROADCAST,
6999 ALLOW_NON_FULL, "getIntentSender", null);
7000 if (origUserId == UserHandle.USER_CURRENT) {
7001 // We don't want to evaluate this until the pending intent is
7002 // actually executed. However, we do want to always do the
7003 // security checking for it above.
7004 userId = UserHandle.USER_CURRENT;
7007 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7008 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7009 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7010 if (!UserHandle.isSameApp(callingUid, uid)) {
7011 String msg = "Permission Denial: getIntentSender() from pid="
7012 + Binder.getCallingPid()
7013 + ", uid=" + Binder.getCallingUid()
7014 + ", (need uid=" + uid + ")"
7015 + " is not allowed to send as package " + packageName;
7017 throw new SecurityException(msg);
7021 return getIntentSenderLocked(type, packageName, callingUid, userId,
7022 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7024 } catch (RemoteException e) {
7025 throw new SecurityException(e);
7030 IIntentSender getIntentSenderLocked(int type, String packageName,
7031 int callingUid, int userId, IBinder token, String resultWho,
7032 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7034 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7035 ActivityRecord activity = null;
7036 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7037 activity = ActivityRecord.isInStackLocked(token);
7038 if (activity == null) {
7039 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7042 if (activity.finishing) {
7043 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7048 // We're going to be splicing together extras before sending, so we're
7049 // okay poking into any contained extras.
7050 if (intents != null) {
7051 for (int i = 0; i < intents.length; i++) {
7052 intents[i].setDefusable(true);
7055 Bundle.setDefusable(bOptions, true);
7057 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7058 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7059 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7060 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7061 |PendingIntent.FLAG_UPDATE_CURRENT);
7063 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7064 type, packageName, activity, resultWho,
7065 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7066 WeakReference<PendingIntentRecord> ref;
7067 ref = mIntentSenderRecords.get(key);
7068 PendingIntentRecord rec = ref != null ? ref.get() : null;
7070 if (!cancelCurrent) {
7071 if (updateCurrent) {
7072 if (rec.key.requestIntent != null) {
7073 rec.key.requestIntent.replaceExtras(intents != null ?
7074 intents[intents.length - 1] : null);
7076 if (intents != null) {
7077 intents[intents.length-1] = rec.key.requestIntent;
7078 rec.key.allIntents = intents;
7079 rec.key.allResolvedTypes = resolvedTypes;
7081 rec.key.allIntents = null;
7082 rec.key.allResolvedTypes = null;
7087 rec.canceled = true;
7088 mIntentSenderRecords.remove(key);
7093 rec = new PendingIntentRecord(this, key, callingUid);
7094 mIntentSenderRecords.put(key, rec.ref);
7095 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7096 if (activity.pendingResults == null) {
7097 activity.pendingResults
7098 = new HashSet<WeakReference<PendingIntentRecord>>();
7100 activity.pendingResults.add(rec.ref);
7106 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7107 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7108 if (target instanceof PendingIntentRecord) {
7109 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7110 finishedReceiver, requiredPermission, options);
7112 if (intent == null) {
7113 // Weird case: someone has given us their own custom IIntentSender, and now
7114 // they have someone else trying to send to it but of course this isn't
7115 // really a PendingIntent, so there is no base Intent, and the caller isn't
7116 // supplying an Intent... but we never want to dispatch a null Intent to
7117 // a receiver, so um... let's make something up.
7118 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7119 intent = new Intent(Intent.ACTION_MAIN);
7122 target.send(code, intent, resolvedType, null, requiredPermission, options);
7123 } catch (RemoteException e) {
7125 // Platform code can rely on getting a result back when the send is done, but if
7126 // this intent sender is from outside of the system we can't rely on it doing that.
7127 // So instead we don't give it the result receiver, and instead just directly
7128 // report the finish immediately.
7129 if (finishedReceiver != null) {
7131 finishedReceiver.performReceive(intent, 0,
7132 null, null, false, false, UserHandle.getCallingUserId());
7133 } catch (RemoteException e) {
7141 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7143 * <p>{@code callerUid} must be allowed to request such whitelist by calling
7144 * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7146 void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7147 if (DEBUG_WHITELISTS) {
7148 Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7149 + targetUid + ", " + duration + ")");
7151 synchronized (mPidsSelfLocked) {
7152 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7154 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7157 if (!pr.whitelistManager) {
7158 if (DEBUG_WHITELISTS) {
7159 Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7160 + callerPid + " is not allowed");
7166 final long token = Binder.clearCallingIdentity();
7168 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7169 true, "pe from uid:" + callerUid);
7171 Binder.restoreCallingIdentity(token);
7176 public void cancelIntentSender(IIntentSender sender) {
7177 if (!(sender instanceof PendingIntentRecord)) {
7180 synchronized(this) {
7181 PendingIntentRecord rec = (PendingIntentRecord)sender;
7183 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7184 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7185 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7186 String msg = "Permission Denial: cancelIntentSender() from pid="
7187 + Binder.getCallingPid()
7188 + ", uid=" + Binder.getCallingUid()
7189 + " is not allowed to cancel packges "
7190 + rec.key.packageName;
7192 throw new SecurityException(msg);
7194 } catch (RemoteException e) {
7195 throw new SecurityException(e);
7197 cancelIntentSenderLocked(rec, true);
7201 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7202 rec.canceled = true;
7203 mIntentSenderRecords.remove(rec.key);
7204 if (cleanActivity && rec.key.activity != null) {
7205 rec.key.activity.pendingResults.remove(rec.ref);
7210 public String getPackageForIntentSender(IIntentSender pendingResult) {
7211 if (!(pendingResult instanceof PendingIntentRecord)) {
7215 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7216 return res.key.packageName;
7217 } catch (ClassCastException e) {
7223 public int getUidForIntentSender(IIntentSender sender) {
7224 if (sender instanceof PendingIntentRecord) {
7226 PendingIntentRecord res = (PendingIntentRecord)sender;
7228 } catch (ClassCastException e) {
7235 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7236 if (!(pendingResult instanceof PendingIntentRecord)) {
7240 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7241 if (res.key.allIntents == null) {
7244 for (int i=0; i<res.key.allIntents.length; i++) {
7245 Intent intent = res.key.allIntents[i];
7246 if (intent.getPackage() != null && intent.getComponent() != null) {
7251 } catch (ClassCastException e) {
7257 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7258 if (!(pendingResult instanceof PendingIntentRecord)) {
7262 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7263 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7267 } catch (ClassCastException e) {
7273 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7274 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7275 "getIntentForIntentSender()");
7276 if (!(pendingResult instanceof PendingIntentRecord)) {
7280 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7281 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7282 } catch (ClassCastException e) {
7288 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7289 if (!(pendingResult instanceof PendingIntentRecord)) {
7293 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7294 synchronized (this) {
7295 return getTagForIntentSenderLocked(res, prefix);
7297 } catch (ClassCastException e) {
7302 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7303 final Intent intent = res.key.requestIntent;
7304 if (intent != null) {
7305 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7306 || res.lastTagPrefix.equals(prefix))) {
7309 res.lastTagPrefix = prefix;
7310 final StringBuilder sb = new StringBuilder(128);
7311 if (prefix != null) {
7314 if (intent.getAction() != null) {
7315 sb.append(intent.getAction());
7316 } else if (intent.getComponent() != null) {
7317 intent.getComponent().appendShortString(sb);
7321 return res.lastTag = sb.toString();
7327 public void setProcessLimit(int max) {
7328 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7329 "setProcessLimit()");
7330 synchronized (this) {
7331 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7332 mProcessLimitOverride = max;
7338 public int getProcessLimit() {
7339 synchronized (this) {
7340 return mProcessLimitOverride;
7344 void foregroundTokenDied(ForegroundToken token) {
7345 synchronized (ActivityManagerService.this) {
7346 synchronized (mPidsSelfLocked) {
7348 = mForegroundProcesses.get(token.pid);
7352 mForegroundProcesses.remove(token.pid);
7353 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7357 pr.forcingToForeground = null;
7358 updateProcessForegroundLocked(pr, false, false);
7360 updateOomAdjLocked();
7365 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7366 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7367 "setProcessForeground()");
7368 synchronized(this) {
7369 boolean changed = false;
7371 synchronized (mPidsSelfLocked) {
7372 ProcessRecord pr = mPidsSelfLocked.get(pid);
7373 if (pr == null && isForeground) {
7374 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7377 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7378 if (oldToken != null) {
7379 oldToken.token.unlinkToDeath(oldToken, 0);
7380 mForegroundProcesses.remove(pid);
7382 pr.forcingToForeground = null;
7386 if (isForeground && token != null) {
7387 ForegroundToken newToken = new ForegroundToken() {
7389 public void binderDied() {
7390 foregroundTokenDied(this);
7394 newToken.token = token;
7396 token.linkToDeath(newToken, 0);
7397 mForegroundProcesses.put(pid, newToken);
7398 pr.forcingToForeground = token;
7400 } catch (RemoteException e) {
7401 // If the process died while doing this, we will later
7402 // do the cleanup with the process death link.
7408 updateOomAdjLocked();
7414 public boolean isAppForeground(int uid) throws RemoteException {
7415 synchronized (this) {
7416 UidRecord uidRec = mActiveUids.get(uid);
7417 if (uidRec == null || uidRec.idle) {
7420 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7424 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7425 // be guarded by permission checking.
7426 int getUidState(int uid) {
7427 synchronized (this) {
7428 UidRecord uidRec = mActiveUids.get(uid);
7429 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7434 public boolean isInMultiWindowMode(IBinder token) {
7435 final long origId = Binder.clearCallingIdentity();
7437 synchronized(this) {
7438 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7442 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7443 return !r.task.mFullscreen;
7446 Binder.restoreCallingIdentity(origId);
7451 public boolean isInPictureInPictureMode(IBinder token) {
7452 final long origId = Binder.clearCallingIdentity();
7454 synchronized(this) {
7455 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7456 if (stack == null) {
7459 return stack.mStackId == PINNED_STACK_ID;
7462 Binder.restoreCallingIdentity(origId);
7467 public void enterPictureInPictureMode(IBinder token) {
7468 final long origId = Binder.clearCallingIdentity();
7470 synchronized(this) {
7471 if (!mSupportsPictureInPicture) {
7472 throw new IllegalStateException("enterPictureInPictureMode: "
7473 + "Device doesn't support picture-in-picture mode.");
7476 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7479 throw new IllegalStateException("enterPictureInPictureMode: "
7480 + "Can't find activity for token=" + token);
7483 if (!r.supportsPictureInPicture()) {
7484 throw new IllegalArgumentException("enterPictureInPictureMode: "
7485 + "Picture-In-Picture not supported for r=" + r);
7488 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7490 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7491 final Rect bounds = (pinnedStack != null)
7492 ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7494 mStackSupervisor.moveActivityToPinnedStackLocked(
7495 r, "enterPictureInPictureMode", bounds);
7498 Binder.restoreCallingIdentity(origId);
7502 // =========================================================
7504 // =========================================================
7506 static class ProcessInfoService extends IProcessInfoService.Stub {
7507 final ActivityManagerService mActivityManagerService;
7508 ProcessInfoService(ActivityManagerService activityManagerService) {
7509 mActivityManagerService = activityManagerService;
7513 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7514 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7515 /*in*/ pids, /*out*/ states, null);
7519 public void getProcessStatesAndOomScoresFromPids(
7520 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7521 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7522 /*in*/ pids, /*out*/ states, /*out*/ scores);
7527 * For each PID in the given input array, write the current process state
7528 * for that process into the states array, or -1 to indicate that no
7529 * process with the given PID exists. If scores array is provided, write
7530 * the oom score for the process into the scores array, with INVALID_ADJ
7531 * indicating the PID doesn't exist.
7533 public void getProcessStatesAndOomScoresForPIDs(
7534 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7535 if (scores != null) {
7536 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7537 "getProcessStatesAndOomScoresForPIDs()");
7541 throw new NullPointerException("pids");
7542 } else if (states == null) {
7543 throw new NullPointerException("states");
7544 } else if (pids.length != states.length) {
7545 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7546 } else if (scores != null && pids.length != scores.length) {
7547 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7550 synchronized (mPidsSelfLocked) {
7551 for (int i = 0; i < pids.length; i++) {
7552 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7553 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7555 if (scores != null) {
7556 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7562 // =========================================================
7564 // =========================================================
7566 static class PermissionController extends IPermissionController.Stub {
7567 ActivityManagerService mActivityManagerService;
7568 PermissionController(ActivityManagerService activityManagerService) {
7569 mActivityManagerService = activityManagerService;
7573 public boolean checkPermission(String permission, int pid, int uid) {
7574 return mActivityManagerService.checkPermission(permission, pid,
7575 uid) == PackageManager.PERMISSION_GRANTED;
7579 public String[] getPackagesForUid(int uid) {
7580 return mActivityManagerService.mContext.getPackageManager()
7581 .getPackagesForUid(uid);
7585 public boolean isRuntimePermission(String permission) {
7587 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7588 .getPermissionInfo(permission, 0);
7589 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7590 } catch (NameNotFoundException nnfe) {
7591 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7597 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7599 public int checkComponentPermission(String permission, int pid, int uid,
7600 int owningUid, boolean exported) {
7601 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7602 owningUid, exported);
7606 public Object getAMSLock() {
7607 return ActivityManagerService.this;
7612 * This can be called with or without the global lock held.
7614 int checkComponentPermission(String permission, int pid, int uid,
7615 int owningUid, boolean exported) {
7616 if (pid == MY_PID) {
7617 return PackageManager.PERMISSION_GRANTED;
7619 return ActivityManager.checkComponentPermission(permission, uid,
7620 owningUid, exported);
7624 * As the only public entry point for permissions checking, this method
7625 * can enforce the semantic that requesting a check on a null global
7626 * permission is automatically denied. (Internally a null permission
7627 * string is used when calling {@link #checkComponentPermission} in cases
7628 * when only uid-based security is needed.)
7630 * This can be called with or without the global lock held.
7633 public int checkPermission(String permission, int pid, int uid) {
7634 if (permission == null) {
7635 return PackageManager.PERMISSION_DENIED;
7637 return checkComponentPermission(permission, pid, uid, -1, true);
7641 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7642 if (permission == null) {
7643 return PackageManager.PERMISSION_DENIED;
7646 // We might be performing an operation on behalf of an indirect binder
7647 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7648 // client identity accordingly before proceeding.
7649 Identity tlsIdentity = sCallerIdentity.get();
7650 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7651 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7652 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7653 uid = tlsIdentity.uid;
7654 pid = tlsIdentity.pid;
7657 return checkComponentPermission(permission, pid, uid, -1, true);
7661 * Binder IPC calls go through the public entry point.
7662 * This can be called with or without the global lock held.
7664 int checkCallingPermission(String permission) {
7665 return checkPermission(permission,
7666 Binder.getCallingPid(),
7667 UserHandle.getAppId(Binder.getCallingUid()));
7671 * This can be called with or without the global lock held.
7673 void enforceCallingPermission(String permission, String func) {
7674 if (checkCallingPermission(permission)
7675 == PackageManager.PERMISSION_GRANTED) {
7679 String msg = "Permission Denial: " + func + " from pid="
7680 + Binder.getCallingPid()
7681 + ", uid=" + Binder.getCallingUid()
7682 + " requires " + permission;
7684 throw new SecurityException(msg);
7688 * Determine if UID is holding permissions required to access {@link Uri} in
7689 * the given {@link ProviderInfo}. Final permission checking is always done
7690 * in {@link ContentProvider}.
7692 private final boolean checkHoldingPermissionsLocked(
7693 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7694 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7695 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7696 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7697 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7698 != PERMISSION_GRANTED) {
7702 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7705 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7706 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7707 if (pi.applicationInfo.uid == uid) {
7709 } else if (!pi.exported) {
7713 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7714 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7716 // check if target holds top-level <provider> permissions
7717 if (!readMet && pi.readPermission != null && considerUidPermissions
7718 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7721 if (!writeMet && pi.writePermission != null && considerUidPermissions
7722 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7726 // track if unprotected read/write is allowed; any denied
7727 // <path-permission> below removes this ability
7728 boolean allowDefaultRead = pi.readPermission == null;
7729 boolean allowDefaultWrite = pi.writePermission == null;
7731 // check if target holds any <path-permission> that match uri
7732 final PathPermission[] pps = pi.pathPermissions;
7734 final String path = grantUri.uri.getPath();
7736 while (i > 0 && (!readMet || !writeMet)) {
7738 PathPermission pp = pps[i];
7739 if (pp.match(path)) {
7741 final String pprperm = pp.getReadPermission();
7742 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7743 "Checking read perm for " + pprperm + " for " + pp.getPath()
7744 + ": match=" + pp.match(path)
7745 + " check=" + pm.checkUidPermission(pprperm, uid));
7746 if (pprperm != null) {
7747 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7748 == PERMISSION_GRANTED) {
7751 allowDefaultRead = false;
7756 final String ppwperm = pp.getWritePermission();
7757 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7758 "Checking write perm " + ppwperm + " for " + pp.getPath()
7759 + ": match=" + pp.match(path)
7760 + " check=" + pm.checkUidPermission(ppwperm, uid));
7761 if (ppwperm != null) {
7762 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7763 == PERMISSION_GRANTED) {
7766 allowDefaultWrite = false;
7774 // grant unprotected <provider> read/write, if not blocked by
7775 // <path-permission> above
7776 if (allowDefaultRead) readMet = true;
7777 if (allowDefaultWrite) writeMet = true;
7779 } catch (RemoteException e) {
7783 return readMet && writeMet;
7786 public int getAppStartMode(int uid, String packageName) {
7787 synchronized (this) {
7788 return checkAllowBackgroundLocked(uid, packageName, -1, true);
7792 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7793 boolean allowWhenForeground) {
7794 UidRecord uidRec = mActiveUids.get(uid);
7795 if (!mLenientBackgroundCheck) {
7796 if (!allowWhenForeground || uidRec == null
7797 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7798 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7799 packageName) != AppOpsManager.MODE_ALLOWED) {
7800 return ActivityManager.APP_START_MODE_DELAYED;
7804 } else if (uidRec == null || uidRec.idle) {
7805 if (callingPid >= 0) {
7807 synchronized (mPidsSelfLocked) {
7808 proc = mPidsSelfLocked.get(callingPid);
7810 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7811 // Whoever is instigating this is in the foreground, so we will allow it
7813 return ActivityManager.APP_START_MODE_NORMAL;
7816 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7817 != AppOpsManager.MODE_ALLOWED) {
7818 return ActivityManager.APP_START_MODE_DELAYED;
7821 return ActivityManager.APP_START_MODE_NORMAL;
7824 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7825 ProviderInfo pi = null;
7826 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7831 pi = AppGlobals.getPackageManager().resolveContentProvider(
7832 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7833 } catch (RemoteException ex) {
7839 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7840 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7841 if (targetUris != null) {
7842 return targetUris.get(grantUri);
7847 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7848 String targetPkg, int targetUid, GrantUri grantUri) {
7849 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7850 if (targetUris == null) {
7851 targetUris = Maps.newArrayMap();
7852 mGrantedUriPermissions.put(targetUid, targetUris);
7855 UriPermission perm = targetUris.get(grantUri);
7857 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7858 targetUris.put(grantUri, perm);
7864 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7865 final int modeFlags) {
7866 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7867 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7868 : UriPermission.STRENGTH_OWNED;
7870 // Root gets to do everything.
7875 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7876 if (perms == null) return false;
7878 // First look for exact match
7879 final UriPermission exactPerm = perms.get(grantUri);
7880 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7884 // No exact match, look for prefixes
7885 final int N = perms.size();
7886 for (int i = 0; i < N; i++) {
7887 final UriPermission perm = perms.valueAt(i);
7888 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7889 && perm.getStrength(modeFlags) >= minStrength) {
7898 * @param uri This uri must NOT contain an embedded userId.
7899 * @param userId The userId in which the uri is to be resolved.
7902 public int checkUriPermission(Uri uri, int pid, int uid,
7903 final int modeFlags, int userId, IBinder callerToken) {
7904 enforceNotIsolatedCaller("checkUriPermission");
7906 // Another redirected-binder-call permissions check as in
7907 // {@link checkPermissionWithToken}.
7908 Identity tlsIdentity = sCallerIdentity.get();
7909 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7910 uid = tlsIdentity.uid;
7911 pid = tlsIdentity.pid;
7914 // Our own process gets to do everything.
7915 if (pid == MY_PID) {
7916 return PackageManager.PERMISSION_GRANTED;
7918 synchronized (this) {
7919 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7920 ? PackageManager.PERMISSION_GRANTED
7921 : PackageManager.PERMISSION_DENIED;
7926 * Check if the targetPkg can be granted permission to access uri by
7927 * the callingUid using the given modeFlags. Throws a security exception
7928 * if callingUid is not allowed to do this. Returns the uid of the target
7929 * if the URI permission grant should be performed; returns -1 if it is not
7930 * needed (for example targetPkg already has permission to access the URI).
7931 * If you already know the uid of the target, you can supply it in
7932 * lastTargetUid else set that to -1.
7934 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7935 final int modeFlags, int lastTargetUid) {
7936 if (!Intent.isAccessUriMode(modeFlags)) {
7940 if (targetPkg != null) {
7941 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7942 "Checking grant " + targetPkg + " permission to " + grantUri);
7945 final IPackageManager pm = AppGlobals.getPackageManager();
7947 // If this is not a content: uri, we can't do anything with it.
7948 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7949 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7950 "Can't grant URI permission for non-content URI: " + grantUri);
7954 final String authority = grantUri.uri.getAuthority();
7955 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7957 Slog.w(TAG, "No content provider found for permission check: " +
7958 grantUri.uri.toSafeString());
7962 int targetUid = lastTargetUid;
7963 if (targetUid < 0 && targetPkg != null) {
7965 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7966 UserHandle.getUserId(callingUid));
7967 if (targetUid < 0) {
7968 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7969 "Can't grant URI permission no uid for: " + targetPkg);
7972 } catch (RemoteException ex) {
7977 if (targetUid >= 0) {
7978 // First... does the target actually need this permission?
7979 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7980 // No need to grant the target this permission.
7981 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7982 "Target " + targetPkg + " already has full permission to " + grantUri);
7986 // First... there is no target package, so can anyone access it?
7987 boolean allowed = pi.exported;
7988 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7989 if (pi.readPermission != null) {
7993 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7994 if (pi.writePermission != null) {
8003 /* There is a special cross user grant if:
8004 * - The target is on another user.
8005 * - Apps on the current user can access the uri without any uid permissions.
8006 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8007 * grant uri permissions.
8009 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8010 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8011 modeFlags, false /*without considering the uid permissions*/);
8013 // Second... is the provider allowing granting of URI permissions?
8014 if (!specialCrossUserGrant) {
8015 if (!pi.grantUriPermissions) {
8016 throw new SecurityException("Provider " + pi.packageName
8018 + " does not allow granting of Uri permissions (uri "
8021 if (pi.uriPermissionPatterns != null) {
8022 final int N = pi.uriPermissionPatterns.length;
8023 boolean allowed = false;
8024 for (int i=0; i<N; i++) {
8025 if (pi.uriPermissionPatterns[i] != null
8026 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8032 throw new SecurityException("Provider " + pi.packageName
8034 + " does not allow granting of permission to path of Uri "
8040 // Third... does the caller itself have permission to access
8042 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8043 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8044 // Require they hold a strong enough Uri permission
8045 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8046 throw new SecurityException("Uid " + callingUid
8047 + " does not have permission to uri " + grantUri);
8055 * @param uri This uri must NOT contain an embedded userId.
8056 * @param userId The userId in which the uri is to be resolved.
8059 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8060 final int modeFlags, int userId) {
8061 enforceNotIsolatedCaller("checkGrantUriPermission");
8062 synchronized(this) {
8063 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8064 new GrantUri(userId, uri, false), modeFlags, -1);
8068 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8069 final int modeFlags, UriPermissionOwner owner) {
8070 if (!Intent.isAccessUriMode(modeFlags)) {
8074 // So here we are: the caller has the assumed permission
8075 // to the uri, and the target doesn't. Let's now give this to
8078 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8081 final String authority = grantUri.uri.getAuthority();
8082 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8084 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8088 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8089 grantUri.prefix = true;
8091 final UriPermission perm = findOrCreateUriPermissionLocked(
8092 pi.packageName, targetPkg, targetUid, grantUri);
8093 perm.grantModes(modeFlags, owner);
8096 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8097 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8098 if (targetPkg == null) {
8099 throw new NullPointerException("targetPkg");
8102 final IPackageManager pm = AppGlobals.getPackageManager();
8104 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8105 } catch (RemoteException ex) {
8109 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8111 if (targetUid < 0) {
8115 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8119 static class NeededUriGrants extends ArrayList<GrantUri> {
8120 final String targetPkg;
8121 final int targetUid;
8124 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8125 this.targetPkg = targetPkg;
8126 this.targetUid = targetUid;
8132 * Like checkGrantUriPermissionLocked, but takes an Intent.
8134 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8135 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8136 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8137 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8138 + " clip=" + (intent != null ? intent.getClipData() : null)
8139 + " from " + intent + "; flags=0x"
8140 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8142 if (targetPkg == null) {
8143 throw new NullPointerException("targetPkg");
8146 if (intent == null) {
8149 Uri data = intent.getData();
8150 ClipData clip = intent.getClipData();
8151 if (data == null && clip == null) {
8154 // Default userId for uris in the intent (if they don't specify it themselves)
8155 int contentUserHint = intent.getContentUserHint();
8156 if (contentUserHint == UserHandle.USER_CURRENT) {
8157 contentUserHint = UserHandle.getUserId(callingUid);
8159 final IPackageManager pm = AppGlobals.getPackageManager();
8161 if (needed != null) {
8162 targetUid = needed.targetUid;
8165 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8167 } catch (RemoteException ex) {
8170 if (targetUid < 0) {
8171 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8172 "Can't grant URI permission no uid for: " + targetPkg
8173 + " on user " + targetUserId);
8178 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8179 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8181 if (targetUid > 0) {
8182 if (needed == null) {
8183 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8185 needed.add(grantUri);
8189 for (int i=0; i<clip.getItemCount(); i++) {
8190 Uri uri = clip.getItemAt(i).getUri();
8192 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8193 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8195 if (targetUid > 0) {
8196 if (needed == null) {
8197 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8199 needed.add(grantUri);
8202 Intent clipIntent = clip.getItemAt(i).getIntent();
8203 if (clipIntent != null) {
8204 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8205 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8206 if (newNeeded != null) {
8218 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8220 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8221 UriPermissionOwner owner) {
8222 if (needed != null) {
8223 for (int i=0; i<needed.size(); i++) {
8224 GrantUri grantUri = needed.get(i);
8225 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8226 grantUri, needed.flags, owner);
8231 void grantUriPermissionFromIntentLocked(int callingUid,
8232 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8233 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8234 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8235 if (needed == null) {
8239 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8243 * @param uri This uri must NOT contain an embedded userId.
8244 * @param userId The userId in which the uri is to be resolved.
8247 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8248 final int modeFlags, int userId) {
8249 enforceNotIsolatedCaller("grantUriPermission");
8250 GrantUri grantUri = new GrantUri(userId, uri, false);
8251 synchronized(this) {
8252 final ProcessRecord r = getRecordForAppLocked(caller);
8254 throw new SecurityException("Unable to find app for caller "
8256 + " when granting permission to uri " + grantUri);
8258 if (targetPkg == null) {
8259 throw new IllegalArgumentException("null target");
8261 if (grantUri == null) {
8262 throw new IllegalArgumentException("null uri");
8265 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8266 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8267 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8268 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8270 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8271 UserHandle.getUserId(r.uid));
8275 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8276 if (perm.modeFlags == 0) {
8277 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8279 if (perms != null) {
8280 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8281 "Removing " + perm.targetUid + " permission to " + perm.uri);
8283 perms.remove(perm.uri);
8284 if (perms.isEmpty()) {
8285 mGrantedUriPermissions.remove(perm.targetUid);
8291 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8292 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8293 "Revoking all granted permissions to " + grantUri);
8295 final IPackageManager pm = AppGlobals.getPackageManager();
8296 final String authority = grantUri.uri.getAuthority();
8297 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8299 Slog.w(TAG, "No content provider found for permission revoke: "
8300 + grantUri.toSafeString());
8304 // Does the caller have this permission on the URI?
8305 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8306 // If they don't have direct access to the URI, then revoke any
8307 // ownerless URI permissions that have been granted to them.
8308 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8309 if (perms != null) {
8310 boolean persistChanged = false;
8311 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8312 final UriPermission perm = it.next();
8313 if (perm.uri.sourceUserId == grantUri.sourceUserId
8314 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8315 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8316 "Revoking non-owned " + perm.targetUid
8317 + " permission to " + perm.uri);
8318 persistChanged |= perm.revokeModes(
8319 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8320 if (perm.modeFlags == 0) {
8325 if (perms.isEmpty()) {
8326 mGrantedUriPermissions.remove(callingUid);
8328 if (persistChanged) {
8329 schedulePersistUriGrants();
8335 boolean persistChanged = false;
8337 // Go through all of the permissions and remove any that match.
8338 int N = mGrantedUriPermissions.size();
8339 for (int i = 0; i < N; i++) {
8340 final int targetUid = mGrantedUriPermissions.keyAt(i);
8341 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8343 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8344 final UriPermission perm = it.next();
8345 if (perm.uri.sourceUserId == grantUri.sourceUserId
8346 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8347 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8348 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8349 persistChanged |= perm.revokeModes(
8350 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8351 if (perm.modeFlags == 0) {
8357 if (perms.isEmpty()) {
8358 mGrantedUriPermissions.remove(targetUid);
8364 if (persistChanged) {
8365 schedulePersistUriGrants();
8370 * @param uri This uri must NOT contain an embedded userId.
8371 * @param userId The userId in which the uri is to be resolved.
8374 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8376 enforceNotIsolatedCaller("revokeUriPermission");
8377 synchronized(this) {
8378 final ProcessRecord r = getRecordForAppLocked(caller);
8380 throw new SecurityException("Unable to find app for caller "
8382 + " when revoking permission to uri " + uri);
8385 Slog.w(TAG, "revokeUriPermission: null uri");
8389 if (!Intent.isAccessUriMode(modeFlags)) {
8393 final String authority = uri.getAuthority();
8394 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8396 Slog.w(TAG, "No content provider found for permission revoke: "
8397 + uri.toSafeString());
8401 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8406 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8409 * @param packageName Package name to match, or {@code null} to apply to all
8411 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8413 * @param persistable If persistable grants should be removed.
8415 private void removeUriPermissionsForPackageLocked(
8416 String packageName, int userHandle, boolean persistable) {
8417 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8418 throw new IllegalArgumentException("Must narrow by either package or user");
8421 boolean persistChanged = false;
8423 int N = mGrantedUriPermissions.size();
8424 for (int i = 0; i < N; i++) {
8425 final int targetUid = mGrantedUriPermissions.keyAt(i);
8426 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8428 // Only inspect grants matching user
8429 if (userHandle == UserHandle.USER_ALL
8430 || userHandle == UserHandle.getUserId(targetUid)) {
8431 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8432 final UriPermission perm = it.next();
8434 // Only inspect grants matching package
8435 if (packageName == null || perm.sourcePkg.equals(packageName)
8436 || perm.targetPkg.equals(packageName)) {
8437 persistChanged |= perm.revokeModes(persistable
8438 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8440 // Only remove when no modes remain; any persisted grants
8441 // will keep this alive.
8442 if (perm.modeFlags == 0) {
8448 if (perms.isEmpty()) {
8449 mGrantedUriPermissions.remove(targetUid);
8456 if (persistChanged) {
8457 schedulePersistUriGrants();
8462 public IBinder newUriPermissionOwner(String name) {
8463 enforceNotIsolatedCaller("newUriPermissionOwner");
8464 synchronized(this) {
8465 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8466 return owner.getExternalTokenLocked();
8471 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8472 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8473 synchronized(this) {
8474 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8476 throw new IllegalArgumentException("Activity does not exist; token="
8479 return r.getUriPermissionsLocked().getExternalTokenLocked();
8483 * @param uri This uri must NOT contain an embedded userId.
8484 * @param sourceUserId The userId in which the uri is to be resolved.
8485 * @param targetUserId The userId of the app that receives the grant.
8488 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8489 final int modeFlags, int sourceUserId, int targetUserId) {
8490 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8491 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8492 "grantUriPermissionFromOwner", null);
8493 synchronized(this) {
8494 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8495 if (owner == null) {
8496 throw new IllegalArgumentException("Unknown owner: " + token);
8498 if (fromUid != Binder.getCallingUid()) {
8499 if (Binder.getCallingUid() != Process.myUid()) {
8500 // Only system code can grant URI permissions on behalf
8502 throw new SecurityException("nice try");
8505 if (targetPkg == null) {
8506 throw new IllegalArgumentException("null target");
8509 throw new IllegalArgumentException("null uri");
8512 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8513 modeFlags, owner, targetUserId);
8518 * @param uri This uri must NOT contain an embedded userId.
8519 * @param userId The userId in which the uri is to be resolved.
8522 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8523 synchronized(this) {
8524 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8525 if (owner == null) {
8526 throw new IllegalArgumentException("Unknown owner: " + token);
8530 owner.removeUriPermissionsLocked(mode);
8532 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8537 private void schedulePersistUriGrants() {
8538 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8539 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8540 10 * DateUtils.SECOND_IN_MILLIS);
8544 private void writeGrantedUriPermissions() {
8545 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8547 // Snapshot permissions so we can persist without lock
8548 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8549 synchronized (this) {
8550 final int size = mGrantedUriPermissions.size();
8551 for (int i = 0; i < size; i++) {
8552 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8553 for (UriPermission perm : perms.values()) {
8554 if (perm.persistedModeFlags != 0) {
8555 persist.add(perm.snapshot());
8561 FileOutputStream fos = null;
8563 fos = mGrantFile.startWrite();
8565 XmlSerializer out = new FastXmlSerializer();
8566 out.setOutput(fos, StandardCharsets.UTF_8.name());
8567 out.startDocument(null, true);
8568 out.startTag(null, TAG_URI_GRANTS);
8569 for (UriPermission.Snapshot perm : persist) {
8570 out.startTag(null, TAG_URI_GRANT);
8571 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8572 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8573 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8574 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8575 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8576 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8577 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8578 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8579 out.endTag(null, TAG_URI_GRANT);
8581 out.endTag(null, TAG_URI_GRANTS);
8584 mGrantFile.finishWrite(fos);
8585 } catch (IOException e) {
8587 mGrantFile.failWrite(fos);
8592 private void readGrantedUriPermissionsLocked() {
8593 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8595 final long now = System.currentTimeMillis();
8597 FileInputStream fis = null;
8599 fis = mGrantFile.openRead();
8600 final XmlPullParser in = Xml.newPullParser();
8601 in.setInput(fis, StandardCharsets.UTF_8.name());
8604 while ((type = in.next()) != END_DOCUMENT) {
8605 final String tag = in.getName();
8606 if (type == START_TAG) {
8607 if (TAG_URI_GRANT.equals(tag)) {
8608 final int sourceUserId;
8609 final int targetUserId;
8610 final int userHandle = readIntAttribute(in,
8611 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8612 if (userHandle != UserHandle.USER_NULL) {
8613 // For backwards compatibility.
8614 sourceUserId = userHandle;
8615 targetUserId = userHandle;
8617 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8618 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8620 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8621 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8622 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8623 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8624 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8625 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8627 // Sanity check that provider still belongs to source package
8628 final ProviderInfo pi = getProviderInfoLocked(
8629 uri.getAuthority(), sourceUserId);
8630 if (pi != null && sourcePkg.equals(pi.packageName)) {
8633 targetUid = AppGlobals.getPackageManager().getPackageUid(
8634 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8635 } catch (RemoteException e) {
8637 if (targetUid != -1) {
8638 final UriPermission perm = findOrCreateUriPermissionLocked(
8639 sourcePkg, targetPkg, targetUid,
8640 new GrantUri(sourceUserId, uri, prefix));
8641 perm.initPersistedModes(modeFlags, createdTime);
8644 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8645 + " but instead found " + pi);
8650 } catch (FileNotFoundException e) {
8651 // Missing grants is okay
8652 } catch (IOException e) {
8653 Slog.wtf(TAG, "Failed reading Uri grants", e);
8654 } catch (XmlPullParserException e) {
8655 Slog.wtf(TAG, "Failed reading Uri grants", e);
8657 IoUtils.closeQuietly(fis);
8662 * @param uri This uri must NOT contain an embedded userId.
8663 * @param userId The userId in which the uri is to be resolved.
8666 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8667 enforceNotIsolatedCaller("takePersistableUriPermission");
8669 Preconditions.checkFlagsArgument(modeFlags,
8670 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8672 synchronized (this) {
8673 final int callingUid = Binder.getCallingUid();
8674 boolean persistChanged = false;
8675 GrantUri grantUri = new GrantUri(userId, uri, false);
8677 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8678 new GrantUri(userId, uri, false));
8679 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8680 new GrantUri(userId, uri, true));
8682 final boolean exactValid = (exactPerm != null)
8683 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8684 final boolean prefixValid = (prefixPerm != null)
8685 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8687 if (!(exactValid || prefixValid)) {
8688 throw new SecurityException("No persistable permission grants found for UID "
8689 + callingUid + " and Uri " + grantUri.toSafeString());
8693 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8696 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8699 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8701 if (persistChanged) {
8702 schedulePersistUriGrants();
8708 * @param uri This uri must NOT contain an embedded userId.
8709 * @param userId The userId in which the uri is to be resolved.
8712 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8713 enforceNotIsolatedCaller("releasePersistableUriPermission");
8715 Preconditions.checkFlagsArgument(modeFlags,
8716 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8718 synchronized (this) {
8719 final int callingUid = Binder.getCallingUid();
8720 boolean persistChanged = false;
8722 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8723 new GrantUri(userId, uri, false));
8724 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8725 new GrantUri(userId, uri, true));
8726 if (exactPerm == null && prefixPerm == null) {
8727 throw new SecurityException("No permission grants found for UID " + callingUid
8728 + " and Uri " + uri.toSafeString());
8731 if (exactPerm != null) {
8732 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8733 removeUriPermissionIfNeededLocked(exactPerm);
8735 if (prefixPerm != null) {
8736 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8737 removeUriPermissionIfNeededLocked(prefixPerm);
8740 if (persistChanged) {
8741 schedulePersistUriGrants();
8747 * Prune any older {@link UriPermission} for the given UID until outstanding
8748 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8750 * @return if any mutations occured that require persisting.
8752 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8753 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8754 if (perms == null) return false;
8755 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8757 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8758 for (UriPermission perm : perms.values()) {
8759 if (perm.persistedModeFlags != 0) {
8760 persisted.add(perm);
8764 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8765 if (trimCount <= 0) return false;
8767 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8768 for (int i = 0; i < trimCount; i++) {
8769 final UriPermission perm = persisted.get(i);
8771 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8772 "Trimming grant created at " + perm.persistedCreateTime);
8774 perm.releasePersistableModes(~0);
8775 removeUriPermissionIfNeededLocked(perm);
8782 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8783 String packageName, boolean incoming) {
8784 enforceNotIsolatedCaller("getPersistedUriPermissions");
8785 Preconditions.checkNotNull(packageName, "packageName");
8787 final int callingUid = Binder.getCallingUid();
8788 final IPackageManager pm = AppGlobals.getPackageManager();
8790 final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8791 UserHandle.getUserId(callingUid));
8792 if (packageUid != callingUid) {
8793 throw new SecurityException(
8794 "Package " + packageName + " does not belong to calling UID " + callingUid);
8796 } catch (RemoteException e) {
8797 throw new SecurityException("Failed to verify package name ownership");
8800 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8801 synchronized (this) {
8803 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8805 if (perms == null) {
8806 Slog.w(TAG, "No permission grants found for " + packageName);
8808 for (UriPermission perm : perms.values()) {
8809 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8810 result.add(perm.buildPersistedPublicApiObject());
8815 final int size = mGrantedUriPermissions.size();
8816 for (int i = 0; i < size; i++) {
8817 final ArrayMap<GrantUri, UriPermission> perms =
8818 mGrantedUriPermissions.valueAt(i);
8819 for (UriPermission perm : perms.values()) {
8820 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8821 result.add(perm.buildPersistedPublicApiObject());
8827 return new ParceledListSlice<android.content.UriPermission>(result);
8831 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8832 String packageName, int userId) {
8833 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8834 "getGrantedUriPermissions");
8836 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8837 synchronized (this) {
8838 final int size = mGrantedUriPermissions.size();
8839 for (int i = 0; i < size; i++) {
8840 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8841 for (UriPermission perm : perms.values()) {
8842 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8843 && perm.persistedModeFlags != 0) {
8844 result.add(perm.buildPersistedPublicApiObject());
8849 return new ParceledListSlice<android.content.UriPermission>(result);
8853 public void clearGrantedUriPermissions(String packageName, int userId) {
8854 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8855 "clearGrantedUriPermissions");
8856 removeUriPermissionsForPackageLocked(packageName, userId, true);
8860 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8861 synchronized (this) {
8863 who != null ? getRecordForAppLocked(who) : null;
8864 if (app == null) return;
8866 Message msg = Message.obtain();
8867 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8869 msg.arg1 = waiting ? 1 : 0;
8870 mUiHandler.sendMessage(msg);
8875 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8876 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8877 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8878 outInfo.availMem = Process.getFreeMemory();
8879 outInfo.totalMem = Process.getTotalMemory();
8880 outInfo.threshold = homeAppMem;
8881 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8882 outInfo.hiddenAppThreshold = cachedAppMem;
8883 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8884 ProcessList.SERVICE_ADJ);
8885 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8886 ProcessList.VISIBLE_APP_ADJ);
8887 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8888 ProcessList.FOREGROUND_APP_ADJ);
8891 // =========================================================
8893 // =========================================================
8896 public List<IAppTask> getAppTasks(String callingPackage) {
8897 int callingUid = Binder.getCallingUid();
8898 long ident = Binder.clearCallingIdentity();
8900 synchronized(this) {
8901 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8903 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8905 final int N = mRecentTasks.size();
8906 for (int i = 0; i < N; i++) {
8907 TaskRecord tr = mRecentTasks.get(i);
8908 // Skip tasks that do not match the caller. We don't need to verify
8909 // callingPackage, because we are also limiting to callingUid and know
8910 // that will limit to the correct security sandbox.
8911 if (tr.effectiveUid != callingUid) {
8914 Intent intent = tr.getBaseIntent();
8915 if (intent == null ||
8916 !callingPackage.equals(intent.getComponent().getPackageName())) {
8919 ActivityManager.RecentTaskInfo taskInfo =
8920 createRecentTaskInfoFromTaskRecord(tr);
8921 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8925 Binder.restoreCallingIdentity(ident);
8932 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8933 final int callingUid = Binder.getCallingUid();
8934 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8936 synchronized(this) {
8937 if (DEBUG_ALL) Slog.v(
8938 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8940 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8943 // TODO: Improve with MRU list from all ActivityStacks.
8944 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8951 * Creates a new RecentTaskInfo from a TaskRecord.
8953 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8954 // Update the task description to reflect any changes in the task stack
8955 tr.updateTaskDescription();
8957 // Compose the recent task info
8958 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8959 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8960 rti.persistentId = tr.taskId;
8961 rti.baseIntent = new Intent(tr.getBaseIntent());
8962 rti.origActivity = tr.origActivity;
8963 rti.realActivity = tr.realActivity;
8964 rti.description = tr.lastDescription;
8965 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8966 rti.userId = tr.userId;
8967 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8968 rti.firstActiveTime = tr.firstActiveTime;
8969 rti.lastActiveTime = tr.lastActiveTime;
8970 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8971 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8972 rti.numActivities = 0;
8973 if (tr.mBounds != null) {
8974 rti.bounds = new Rect(tr.mBounds);
8976 rti.isDockable = tr.canGoInDockedStack();
8977 rti.resizeMode = tr.mResizeMode;
8979 ActivityRecord base = null;
8980 ActivityRecord top = null;
8983 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8984 tmp = tr.mActivities.get(i);
8985 if (tmp.finishing) {
8989 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8992 rti.numActivities++;
8995 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8996 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9001 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9002 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9003 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9005 if (checkPermission(android.Manifest.permission.GET_TASKS,
9006 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9007 // Temporary compatibility: some existing apps on the system image may
9008 // still be requesting the old permission and not switched to the new
9009 // one; if so, we'll still allow them full access. This means we need
9010 // to see if they are holding the old permission and are a system app.
9012 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9014 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9015 + " is using old GET_TASKS but privileged; allowing");
9017 } catch (RemoteException e) {
9022 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9023 + " does not hold REAL_GET_TASKS; limiting output");
9029 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
9030 final int callingUid = Binder.getCallingUid();
9031 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9032 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9034 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9035 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9036 synchronized (this) {
9037 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9039 final boolean detailed = checkCallingPermission(
9040 android.Manifest.permission.GET_DETAILED_TASKS)
9041 == PackageManager.PERMISSION_GRANTED;
9043 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9044 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9045 return Collections.emptyList();
9047 mRecentTasks.loadUserRecentsLocked(userId);
9049 final int recentsCount = mRecentTasks.size();
9050 ArrayList<ActivityManager.RecentTaskInfo> res =
9051 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9053 final Set<Integer> includedUsers;
9054 if (includeProfiles) {
9055 includedUsers = mUserController.getProfileIds(userId);
9057 includedUsers = new HashSet<>();
9059 includedUsers.add(Integer.valueOf(userId));
9061 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9062 TaskRecord tr = mRecentTasks.get(i);
9063 // Only add calling user or related users recent tasks
9064 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9065 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9069 if (tr.realActivitySuspended) {
9070 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9074 // Return the entry if desired by the caller. We always return
9075 // the first entry, because callers always expect this to be the
9076 // foreground app. We may filter others if the caller has
9077 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9078 // we should exclude the entry.
9082 || (tr.intent == null)
9083 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9086 // If the caller doesn't have the GET_TASKS permission, then only
9087 // allow them to see a small subset of tasks -- their own and home.
9088 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9089 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9093 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9094 if (tr.stack != null && tr.stack.isHomeStack()) {
9095 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9096 "Skipping, home stack task: " + tr);
9100 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9101 final ActivityStack stack = tr.stack;
9102 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9103 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9104 "Skipping, top task in docked stack: " + tr);
9108 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9109 if (tr.stack != null && tr.stack.isPinnedStack()) {
9110 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9111 "Skipping, pinned stack task: " + tr);
9115 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9116 // Don't include auto remove tasks that are finished or finishing.
9117 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9118 "Skipping, auto-remove without activity: " + tr);
9121 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9122 && !tr.isAvailable) {
9123 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9124 "Skipping, unavail real act: " + tr);
9128 if (!tr.mUserSetupComplete) {
9129 // Don't include task launched while user is not done setting-up.
9130 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9131 "Skipping, user setup not complete: " + tr);
9135 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9137 rti.baseIntent.replaceExtras((Bundle)null);
9149 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9150 synchronized (this) {
9151 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9152 "getTaskThumbnail()");
9153 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9154 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9156 return tr.getTaskThumbnailLocked();
9163 public int addAppTask(IBinder activityToken, Intent intent,
9164 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9165 final int callingUid = Binder.getCallingUid();
9166 final long callingIdent = Binder.clearCallingIdentity();
9169 synchronized (this) {
9170 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9172 throw new IllegalArgumentException("Activity does not exist; token="
9175 ComponentName comp = intent.getComponent();
9177 throw new IllegalArgumentException("Intent " + intent
9178 + " must specify explicit component");
9180 if (thumbnail.getWidth() != mThumbnailWidth
9181 || thumbnail.getHeight() != mThumbnailHeight) {
9182 throw new IllegalArgumentException("Bad thumbnail size: got "
9183 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9184 + mThumbnailWidth + "x" + mThumbnailHeight);
9186 if (intent.getSelector() != null) {
9187 intent.setSelector(null);
9189 if (intent.getSourceBounds() != null) {
9190 intent.setSourceBounds(null);
9192 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9193 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9194 // The caller has added this as an auto-remove task... that makes no
9195 // sense, so turn off auto-remove.
9196 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9198 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
9199 // Must be a new task.
9200 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
9202 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9203 mLastAddedTaskActivity = null;
9205 ActivityInfo ainfo = mLastAddedTaskActivity;
9206 if (ainfo == null) {
9207 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9208 comp, 0, UserHandle.getUserId(callingUid));
9209 if (ainfo.applicationInfo.uid != callingUid) {
9210 throw new SecurityException(
9211 "Can't add task for another application: target uid="
9212 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9216 // Use the full screen as the context for the task thumbnail
9217 final Point displaySize = new Point();
9218 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9219 r.task.stack.getDisplaySize(displaySize);
9220 thumbnailInfo.taskWidth = displaySize.x;
9221 thumbnailInfo.taskHeight = displaySize.y;
9222 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9224 TaskRecord task = new TaskRecord(this,
9225 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9226 ainfo, intent, description, thumbnailInfo);
9228 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9230 // If this would have caused a trim, then we'll abort because that
9231 // means it would be added at the end of the list but then just removed.
9232 return INVALID_TASK_ID;
9235 final int N = mRecentTasks.size();
9236 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9237 final TaskRecord tr = mRecentTasks.remove(N - 1);
9238 tr.removedFromRecents();
9241 task.inRecents = true;
9242 mRecentTasks.add(task);
9243 r.task.stack.addTask(task, false, "addAppTask");
9245 task.setLastThumbnailLocked(thumbnail);
9246 task.freeLastThumbnail();
9251 Binder.restoreCallingIdentity(callingIdent);
9256 public Point getAppTaskThumbnailSize() {
9257 synchronized (this) {
9258 return new Point(mThumbnailWidth, mThumbnailHeight);
9263 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9264 synchronized (this) {
9265 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9267 r.setTaskDescription(td);
9268 r.task.updateTaskDescription();
9274 public void setTaskResizeable(int taskId, int resizeableMode) {
9275 synchronized (this) {
9276 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9277 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9279 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9282 if (task.mResizeMode != resizeableMode) {
9283 task.mResizeMode = resizeableMode;
9284 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9285 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9286 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9292 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9293 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9294 long ident = Binder.clearCallingIdentity();
9296 synchronized (this) {
9297 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9299 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9302 int stackId = task.stack.mStackId;
9303 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9304 // in crop windows resize mode or if the task size is affected by the docked stack
9305 // changing size. No need to update configuration.
9306 if (bounds != null && task.inCropWindowsResizeMode()
9307 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9308 mWindowManager.scrollTask(task.taskId, bounds);
9312 // Place the task in the right stack if it isn't there already based on
9313 // the requested bounds.
9314 // The stack transition logic is:
9315 // - a null bounds on a freeform task moves that task to fullscreen
9316 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9317 // that task to freeform
9318 // - otherwise the task is not moved
9319 if (!StackId.isTaskResizeAllowed(stackId)) {
9320 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9322 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9323 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9324 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9325 stackId = FREEFORM_WORKSPACE_STACK_ID;
9327 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9328 if (stackId != task.stack.mStackId) {
9329 mStackSupervisor.moveTaskToStackUncheckedLocked(
9330 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9331 preserveWindow = false;
9334 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9335 false /* deferResume */);
9338 Binder.restoreCallingIdentity(ident);
9343 public Rect getTaskBounds(int taskId) {
9344 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9345 long ident = Binder.clearCallingIdentity();
9346 Rect rect = new Rect();
9348 synchronized (this) {
9349 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9350 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9352 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9355 if (task.stack != null) {
9356 // Return the bounds from window manager since it will be adjusted for various
9357 // things like the presense of a docked stack for tasks that aren't resizeable.
9358 mWindowManager.getTaskBounds(task.taskId, rect);
9360 // Task isn't in window manager yet since it isn't associated with a stack.
9361 // Return the persist value from activity manager
9362 if (task.mBounds != null) {
9363 rect.set(task.mBounds);
9364 } else if (task.mLastNonFullscreenBounds != null) {
9365 rect.set(task.mLastNonFullscreenBounds);
9370 Binder.restoreCallingIdentity(ident);
9376 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9377 if (userId != UserHandle.getCallingUserId()) {
9378 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9379 "getTaskDescriptionIcon");
9381 final File passedIconFile = new File(filePath);
9382 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9383 passedIconFile.getName());
9384 if (!legitIconFile.getPath().equals(filePath)
9385 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9386 throw new IllegalArgumentException("Bad file path: " + filePath
9387 + " passed for userId " + userId);
9389 return mRecentTasks.getTaskDescriptionIcon(filePath);
9393 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9394 throws RemoteException {
9395 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9396 opts.getCustomInPlaceResId() == 0) {
9397 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9398 "with valid animation");
9400 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9401 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9402 opts.getCustomInPlaceResId());
9403 mWindowManager.executeAppTransition();
9406 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9407 boolean removeFromRecents) {
9408 if (removeFromRecents) {
9409 mRecentTasks.remove(tr);
9410 tr.removedFromRecents();
9412 ComponentName component = tr.getBaseIntent().getComponent();
9413 if (component == null) {
9414 Slog.w(TAG, "No component for base intent of task: " + tr);
9418 // Find any running services associated with this app and stop if needed.
9419 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9425 // Determine if the process(es) for this task should be killed.
9426 final String pkg = component.getPackageName();
9427 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9428 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9429 for (int i = 0; i < pmap.size(); i++) {
9431 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9432 for (int j = 0; j < uids.size(); j++) {
9433 ProcessRecord proc = uids.valueAt(j);
9434 if (proc.userId != tr.userId) {
9435 // Don't kill process for a different user.
9438 if (proc == mHomeProcess) {
9439 // Don't kill the home process along with tasks from the same package.
9442 if (!proc.pkgList.containsKey(pkg)) {
9443 // Don't kill process that is not associated with this task.
9447 for (int k = 0; k < proc.activities.size(); k++) {
9448 TaskRecord otherTask = proc.activities.get(k).task;
9449 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9450 // Don't kill process(es) that has an activity in a different task that is
9456 if (proc.foregroundServices) {
9457 // Don't kill process(es) with foreground service.
9461 // Add process to kill list.
9462 procsToKill.add(proc);
9466 // Kill the running processes.
9467 for (int i = 0; i < procsToKill.size(); i++) {
9468 ProcessRecord pr = procsToKill.get(i);
9469 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9470 && pr.curReceiver == null) {
9471 pr.kill("remove task", true);
9473 // We delay killing processes that are not in the background or running a receiver.
9474 pr.waitingToKill = "remove task";
9479 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9480 // Remove all tasks with activities in the specified package from the list of recent tasks
9481 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9482 TaskRecord tr = mRecentTasks.get(i);
9483 if (tr.userId != userId) continue;
9485 ComponentName cn = tr.intent.getComponent();
9486 if (cn != null && cn.getPackageName().equals(packageName)) {
9487 // If the package name matches, remove the task.
9488 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9493 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9496 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9497 TaskRecord tr = mRecentTasks.get(i);
9498 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9502 ComponentName cn = tr.intent.getComponent();
9503 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9504 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9505 if (sameComponent) {
9506 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9512 * Removes the task with the specified task id.
9514 * @param taskId Identifier of the task to be removed.
9515 * @param killProcess Kill any process associated with the task if possible.
9516 * @param removeFromRecents Whether to also remove the task from recents.
9517 * @return Returns true if the given task was found and removed.
9519 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9520 boolean removeFromRecents) {
9521 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9522 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9524 tr.removeTaskActivitiesLocked();
9525 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9526 if (tr.isPersistable) {
9527 notifyTaskPersisterLocked(null, true);
9531 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9536 public void removeStack(int stackId) {
9537 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9538 if (stackId == HOME_STACK_ID) {
9539 throw new IllegalArgumentException("Removing home stack is not allowed.");
9542 synchronized (this) {
9543 final long ident = Binder.clearCallingIdentity();
9545 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9546 if (stack == null) {
9549 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9550 for (int i = tasks.size() - 1; i >= 0; i--) {
9551 removeTaskByIdLocked(
9552 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9555 Binder.restoreCallingIdentity(ident);
9561 public boolean removeTask(int taskId) {
9562 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9563 synchronized (this) {
9564 final long ident = Binder.clearCallingIdentity();
9566 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9568 Binder.restoreCallingIdentity(ident);
9574 * TODO: Add mController hook
9577 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9578 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9580 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9581 synchronized(this) {
9582 moveTaskToFrontLocked(taskId, flags, bOptions);
9586 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9587 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9589 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9590 Binder.getCallingUid(), -1, -1, "Task to front")) {
9591 ActivityOptions.abort(options);
9594 final long origId = Binder.clearCallingIdentity();
9596 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9598 Slog.d(TAG, "Could not find task for id: "+ taskId);
9601 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9602 mStackSupervisor.showLockTaskToast();
9603 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9606 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9607 if (prev != null && prev.isRecentsActivity()) {
9608 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9610 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9611 false /* forceNonResizable */);
9613 Binder.restoreCallingIdentity(origId);
9615 ActivityOptions.abort(options);
9619 * Moves an activity, and all of the other activities within the same task, to the bottom
9620 * of the history stack. The activity's order within the task is unchanged.
9622 * @param token A reference to the activity we wish to move
9623 * @param nonRoot If false then this only works if the activity is the root
9624 * of a task; if true it will work for any activity in a task.
9625 * @return Returns true if the move completed, false if not.
9628 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9629 enforceNotIsolatedCaller("moveActivityTaskToBack");
9630 synchronized(this) {
9631 final long origId = Binder.clearCallingIdentity();
9633 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9634 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9636 if (mStackSupervisor.isLockedTask(task)) {
9637 mStackSupervisor.showLockTaskToast();
9640 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9643 Binder.restoreCallingIdentity(origId);
9650 public void moveTaskBackwards(int task) {
9651 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9652 "moveTaskBackwards()");
9654 synchronized(this) {
9655 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9656 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9659 final long origId = Binder.clearCallingIdentity();
9660 moveTaskBackwardsLocked(task);
9661 Binder.restoreCallingIdentity(origId);
9665 private final void moveTaskBackwardsLocked(int task) {
9666 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9670 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9671 IActivityContainerCallback callback) throws RemoteException {
9672 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9673 synchronized (this) {
9674 if (parentActivityToken == null) {
9675 throw new IllegalArgumentException("parent token must not be null");
9677 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9681 if (callback == null) {
9682 throw new IllegalArgumentException("callback must not be null");
9684 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9689 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9690 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9691 synchronized (this) {
9692 mStackSupervisor.deleteActivityContainer(container);
9697 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9698 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9699 synchronized (this) {
9700 final int stackId = mStackSupervisor.getNextStackId();
9701 final ActivityStack stack =
9702 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9703 if (stack == null) {
9706 return stack.mActivityContainer;
9711 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9712 synchronized (this) {
9713 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9714 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9715 return stack.mActivityContainer.getDisplayId();
9717 return Display.DEFAULT_DISPLAY;
9722 public int getActivityStackId(IBinder token) throws RemoteException {
9723 synchronized (this) {
9724 ActivityStack stack = ActivityRecord.getStackLocked(token);
9725 if (stack == null) {
9726 return INVALID_STACK_ID;
9728 return stack.mStackId;
9733 public void exitFreeformMode(IBinder token) throws RemoteException {
9734 synchronized (this) {
9735 long ident = Binder.clearCallingIdentity();
9737 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9739 throw new IllegalArgumentException(
9740 "exitFreeformMode: No activity record matching token=" + token);
9742 final ActivityStack stack = r.getStackLocked(token);
9743 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9744 throw new IllegalStateException(
9745 "exitFreeformMode: You can only go fullscreen from freeform.");
9747 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9748 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9749 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9751 Binder.restoreCallingIdentity(ident);
9757 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9758 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9759 if (stackId == HOME_STACK_ID) {
9760 throw new IllegalArgumentException(
9761 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9763 synchronized (this) {
9764 long ident = Binder.clearCallingIdentity();
9766 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9767 + " to stackId=" + stackId + " toTop=" + toTop);
9768 if (stackId == DOCKED_STACK_ID) {
9769 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9770 null /* initialBounds */);
9772 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9773 !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9774 if (result && stackId == DOCKED_STACK_ID) {
9775 // If task moved to docked stack - show recents if needed.
9776 mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9777 "moveTaskToDockedStack");
9780 Binder.restoreCallingIdentity(ident);
9786 public void swapDockedAndFullscreenStack() throws RemoteException {
9787 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9788 synchronized (this) {
9789 long ident = Binder.clearCallingIdentity();
9791 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9792 FULLSCREEN_WORKSPACE_STACK_ID);
9793 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9795 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9796 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9798 if (topTask == null || tasks == null || tasks.size() == 0) {
9800 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9804 // TODO: App transition
9805 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9807 // Defer the resume so resume/pausing while moving stacks is dangerous.
9808 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9809 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9810 ANIMATE, true /* deferResume */);
9811 final int size = tasks.size();
9812 for (int i = 0; i < size; i++) {
9813 final int id = tasks.get(i).taskId;
9814 if (id == topTask.taskId) {
9817 mStackSupervisor.moveTaskToStackLocked(id,
9818 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9819 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9822 // Because we deferred the resume, to avoid conflicts with stack switches while
9823 // resuming, we need to do it after all the tasks are moved.
9824 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9825 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9827 mWindowManager.executeAppTransition();
9829 Binder.restoreCallingIdentity(ident);
9835 * Moves the input task to the docked stack.
9837 * @param taskId Id of task to move.
9838 * @param createMode The mode the docked stack should be created in if it doesn't exist
9840 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9842 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9843 * @param toTop If the task and stack should be moved to the top.
9844 * @param animate Whether we should play an animation for the moving the task
9845 * @param initialBounds If the docked stack gets created, it will use these bounds for the
9846 * docked stack. Pass {@code null} to use default bounds.
9849 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9850 Rect initialBounds, boolean moveHomeStackFront) {
9851 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9852 synchronized (this) {
9853 long ident = Binder.clearCallingIdentity();
9855 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9856 + " to createMode=" + createMode + " toTop=" + toTop);
9857 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9858 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9859 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9860 animate, DEFER_RESUME);
9862 if (moveHomeStackFront) {
9863 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9865 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9869 Binder.restoreCallingIdentity(ident);
9875 * Moves the top activity in the input stackId to the pinned stack.
9877 * @param stackId Id of stack to move the top activity to pinned stack.
9878 * @param bounds Bounds to use for pinned stack.
9880 * @return True if the top activity of the input stack was successfully moved to the pinned
9884 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9885 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9886 synchronized (this) {
9887 if (!mSupportsPictureInPicture) {
9888 throw new IllegalStateException("moveTopActivityToPinnedStack:"
9889 + "Device doesn't support picture-in-pciture mode");
9892 long ident = Binder.clearCallingIdentity();
9894 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9896 Binder.restoreCallingIdentity(ident);
9902 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9903 boolean preserveWindows, boolean animate, int animationDuration) {
9904 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9905 long ident = Binder.clearCallingIdentity();
9907 synchronized (this) {
9909 if (stackId == PINNED_STACK_ID) {
9910 mWindowManager.animateResizePinnedStack(bounds, animationDuration);
9912 throw new IllegalArgumentException("Stack: " + stackId
9913 + " doesn't support animated resize.");
9916 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9917 null /* tempTaskInsetBounds */, preserveWindows,
9918 allowResizeInDockedMode, !DEFER_RESUME);
9922 Binder.restoreCallingIdentity(ident);
9927 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9928 Rect tempDockedTaskInsetBounds,
9929 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9930 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9931 "resizeDockedStack()");
9932 long ident = Binder.clearCallingIdentity();
9934 synchronized (this) {
9935 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9936 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9940 Binder.restoreCallingIdentity(ident);
9945 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9946 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9947 "resizePinnedStack()");
9948 final long ident = Binder.clearCallingIdentity();
9950 synchronized (this) {
9951 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9954 Binder.restoreCallingIdentity(ident);
9959 public void positionTaskInStack(int taskId, int stackId, int position) {
9960 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9961 if (stackId == HOME_STACK_ID) {
9962 throw new IllegalArgumentException(
9963 "positionTaskInStack: Attempt to change the position of task "
9964 + taskId + " in/to home stack");
9966 synchronized (this) {
9967 long ident = Binder.clearCallingIdentity();
9969 if (DEBUG_STACK) Slog.d(TAG_STACK,
9970 "positionTaskInStack: positioning task=" + taskId
9971 + " in stackId=" + stackId + " at position=" + position);
9972 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9974 Binder.restoreCallingIdentity(ident);
9980 public List<StackInfo> getAllStackInfos() {
9981 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9982 long ident = Binder.clearCallingIdentity();
9984 synchronized (this) {
9985 return mStackSupervisor.getAllStackInfosLocked();
9988 Binder.restoreCallingIdentity(ident);
9993 public StackInfo getStackInfo(int stackId) {
9994 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9995 long ident = Binder.clearCallingIdentity();
9997 synchronized (this) {
9998 return mStackSupervisor.getStackInfoLocked(stackId);
10001 Binder.restoreCallingIdentity(ident);
10006 public boolean isInHomeStack(int taskId) {
10007 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10008 long ident = Binder.clearCallingIdentity();
10010 synchronized (this) {
10011 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10012 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10013 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10016 Binder.restoreCallingIdentity(ident);
10021 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10022 synchronized(this) {
10023 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10028 public void updateDeviceOwner(String packageName) {
10029 final int callingUid = Binder.getCallingUid();
10030 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10031 throw new SecurityException("updateDeviceOwner called from non-system process");
10033 synchronized (this) {
10034 mDeviceOwnerName = packageName;
10039 public void updateLockTaskPackages(int userId, String[] packages) {
10040 final int callingUid = Binder.getCallingUid();
10041 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10042 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10043 "updateLockTaskPackages()");
10045 synchronized (this) {
10046 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10047 Arrays.toString(packages));
10048 mLockTaskPackages.put(userId, packages);
10049 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10054 void startLockTaskModeLocked(TaskRecord task) {
10055 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10056 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10060 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10061 // is initiated by system after the pinning request was shown and locked mode is initiated
10062 // by an authorized app directly
10063 final int callingUid = Binder.getCallingUid();
10064 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10065 long ident = Binder.clearCallingIdentity();
10067 if (!isSystemInitiated) {
10068 task.mLockTaskUid = callingUid;
10069 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10070 // startLockTask() called by app and task mode is lockTaskModeDefault.
10071 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10072 StatusBarManagerInternal statusBarManager =
10073 LocalServices.getService(StatusBarManagerInternal.class);
10074 if (statusBarManager != null) {
10075 statusBarManager.showScreenPinningRequest(task.taskId);
10080 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10081 if (stack == null || task != stack.topTask()) {
10082 throw new IllegalArgumentException("Invalid task, not in foreground");
10085 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10087 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10088 ActivityManager.LOCK_TASK_MODE_PINNED :
10089 ActivityManager.LOCK_TASK_MODE_LOCKED,
10090 "startLockTask", true);
10092 Binder.restoreCallingIdentity(ident);
10097 public void startLockTaskMode(int taskId) {
10098 synchronized (this) {
10099 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10100 if (task != null) {
10101 startLockTaskModeLocked(task);
10107 public void startLockTaskMode(IBinder token) {
10108 synchronized (this) {
10109 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10113 final TaskRecord task = r.task;
10114 if (task != null) {
10115 startLockTaskModeLocked(task);
10121 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10122 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10123 // This makes inner call to look as if it was initiated by system.
10124 long ident = Binder.clearCallingIdentity();
10126 synchronized (this) {
10127 startLockTaskMode(taskId);
10130 Binder.restoreCallingIdentity(ident);
10135 public void stopLockTaskMode() {
10136 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10137 if (lockTask == null) {
10138 // Our work here is done.
10142 final int callingUid = Binder.getCallingUid();
10143 final int lockTaskUid = lockTask.mLockTaskUid;
10144 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10145 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10149 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10150 // It is possible lockTaskMode was started by the system process because
10151 // android:lockTaskMode is set to a locking value in the application manifest
10152 // instead of the app calling startLockTaskMode. In this case
10153 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10154 // {@link TaskRecord.effectiveUid} instead. Also caller with
10155 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10156 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10157 && callingUid != lockTaskUid
10158 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10159 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10160 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10163 long ident = Binder.clearCallingIdentity();
10165 Log.d(TAG, "stopLockTaskMode");
10167 synchronized (this) {
10168 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10169 "stopLockTask", true);
10171 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10173 tm.showInCallScreen(false);
10176 Binder.restoreCallingIdentity(ident);
10181 * This API should be called by SystemUI only when user perform certain action to dismiss
10182 * lock task mode. We should only dismiss pinned lock task mode in this case.
10185 public void stopSystemLockTaskMode() throws RemoteException {
10186 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10187 stopLockTaskMode();
10189 mStackSupervisor.showLockTaskToast();
10194 public boolean isInLockTaskMode() {
10195 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10199 public int getLockTaskModeState() {
10200 synchronized (this) {
10201 return mStackSupervisor.getLockTaskModeState();
10206 public void showLockTaskEscapeMessage(IBinder token) {
10207 synchronized (this) {
10208 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10212 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10216 // =========================================================
10217 // CONTENT PROVIDERS
10218 // =========================================================
10220 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10221 List<ProviderInfo> providers = null;
10223 providers = AppGlobals.getPackageManager()
10224 .queryContentProviders(app.processName, app.uid,
10225 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10226 | MATCH_DEBUG_TRIAGED_MISSING)
10228 } catch (RemoteException ex) {
10230 if (DEBUG_MU) Slog.v(TAG_MU,
10231 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10232 int userId = app.userId;
10233 if (providers != null) {
10234 int N = providers.size();
10235 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10236 for (int i=0; i<N; i++) {
10237 // TODO: keep logic in sync with installEncryptionUnawareProviders
10239 (ProviderInfo)providers.get(i);
10240 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10241 cpi.name, cpi.flags);
10242 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10243 // This is a singleton provider, but a user besides the
10244 // default user is asking to initialize a process it runs
10245 // in... well, no, it doesn't actually run in this process,
10246 // it runs in the process of the default user. Get rid of it.
10247 providers.remove(i);
10253 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10254 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10256 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10257 mProviderMap.putProviderByClass(comp, cpr);
10259 if (DEBUG_MU) Slog.v(TAG_MU,
10260 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10261 app.pubProviders.put(cpi.name, cpr);
10262 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10263 // Don't add this if it is a platform component that is marked
10264 // to run in multiple processes, because this is actually
10265 // part of the framework so doesn't make sense to track as a
10266 // separate apk in the process.
10267 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10270 notifyPackageUse(cpi.applicationInfo.packageName,
10271 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10278 * Check if {@link ProcessRecord} has a possible chance at accessing the
10279 * given {@link ProviderInfo}. Final permission checking is always done
10280 * in {@link ContentProvider}.
10282 private final String checkContentProviderPermissionLocked(
10283 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10284 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10285 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10286 boolean checkedGrants = false;
10288 // Looking for cross-user grants before enforcing the typical cross-users permissions
10289 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10290 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10291 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10294 checkedGrants = true;
10296 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10297 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10298 if (userId != tmpTargetUserId) {
10299 // When we actually went to determine the final targer user ID, this ended
10300 // up different than our initial check for the authority. This is because
10301 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10302 // SELF. So we need to re-check the grants again.
10303 checkedGrants = false;
10306 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10307 cpi.applicationInfo.uid, cpi.exported)
10308 == PackageManager.PERMISSION_GRANTED) {
10311 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10312 cpi.applicationInfo.uid, cpi.exported)
10313 == PackageManager.PERMISSION_GRANTED) {
10317 PathPermission[] pps = cpi.pathPermissions;
10319 int i = pps.length;
10322 PathPermission pp = pps[i];
10323 String pprperm = pp.getReadPermission();
10324 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10325 cpi.applicationInfo.uid, cpi.exported)
10326 == PackageManager.PERMISSION_GRANTED) {
10329 String ppwperm = pp.getWritePermission();
10330 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10331 cpi.applicationInfo.uid, cpi.exported)
10332 == PackageManager.PERMISSION_GRANTED) {
10337 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10342 if (!cpi.exported) {
10343 msg = "Permission Denial: opening provider " + cpi.name
10344 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10345 + ", uid=" + callingUid + ") that is not exported from uid "
10346 + cpi.applicationInfo.uid;
10348 msg = "Permission Denial: opening provider " + cpi.name
10349 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10350 + ", uid=" + callingUid + ") requires "
10351 + cpi.readPermission + " or " + cpi.writePermission;
10358 * Returns if the ContentProvider has granted a uri to callingUid
10360 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10361 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10362 if (perms != null) {
10363 for (int i=perms.size()-1; i>=0; i--) {
10364 GrantUri grantUri = perms.keyAt(i);
10365 if (grantUri.sourceUserId == userId || !checkUser) {
10366 if (matchesProvider(grantUri.uri, cpi)) {
10376 * Returns true if the uri authority is one of the authorities specified in the provider.
10378 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10379 String uriAuth = uri.getAuthority();
10380 String cpiAuth = cpi.authority;
10381 if (cpiAuth.indexOf(';') == -1) {
10382 return cpiAuth.equals(uriAuth);
10384 String[] cpiAuths = cpiAuth.split(";");
10385 int length = cpiAuths.length;
10386 for (int i = 0; i < length; i++) {
10387 if (cpiAuths[i].equals(uriAuth)) return true;
10392 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10393 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10395 for (int i=0; i<r.conProviders.size(); i++) {
10396 ContentProviderConnection conn = r.conProviders.get(i);
10397 if (conn.provider == cpr) {
10398 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10399 "Adding provider requested by "
10400 + r.processName + " from process "
10401 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10402 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10404 conn.stableCount++;
10405 conn.numStableIncs++;
10407 conn.unstableCount++;
10408 conn.numUnstableIncs++;
10413 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10415 conn.stableCount = 1;
10416 conn.numStableIncs = 1;
10418 conn.unstableCount = 1;
10419 conn.numUnstableIncs = 1;
10421 cpr.connections.add(conn);
10422 r.conProviders.add(conn);
10423 startAssociationLocked(r.uid, r.processName, r.curProcState,
10424 cpr.uid, cpr.name, cpr.info.processName);
10427 cpr.addExternalProcessHandleLocked(externalProcessToken);
10431 boolean decProviderCountLocked(ContentProviderConnection conn,
10432 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10433 if (conn != null) {
10434 cpr = conn.provider;
10435 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10436 "Removing provider requested by "
10437 + conn.client.processName + " from process "
10438 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10439 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10441 conn.stableCount--;
10443 conn.unstableCount--;
10445 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10446 cpr.connections.remove(conn);
10447 conn.client.conProviders.remove(conn);
10448 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10449 // The client is more important than last activity -- note the time this
10450 // is happening, so we keep the old provider process around a bit as last
10451 // activity to avoid thrashing it.
10452 if (cpr.proc != null) {
10453 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10456 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10461 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10465 private void checkTime(long startTime, String where) {
10466 long now = SystemClock.uptimeMillis();
10467 if ((now-startTime) > 50) {
10468 // If we are taking more than 50ms, log about it.
10469 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10473 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10474 String name, IBinder token, boolean stable, int userId) {
10475 ContentProviderRecord cpr;
10476 ContentProviderConnection conn = null;
10477 ProviderInfo cpi = null;
10479 synchronized(this) {
10480 long startTime = SystemClock.uptimeMillis();
10482 ProcessRecord r = null;
10483 if (caller != null) {
10484 r = getRecordForAppLocked(caller);
10486 throw new SecurityException(
10487 "Unable to find app for caller " + caller
10488 + " (pid=" + Binder.getCallingPid()
10489 + ") when getting content provider " + name);
10493 boolean checkCrossUser = true;
10495 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10497 // First check if this content provider has been published...
10498 cpr = mProviderMap.getProviderByName(name, userId);
10499 // If that didn't work, check if it exists for user 0 and then
10500 // verify that it's a singleton provider before using it.
10501 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10502 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10505 if (isSingleton(cpi.processName, cpi.applicationInfo,
10506 cpi.name, cpi.flags)
10507 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10508 userId = UserHandle.USER_SYSTEM;
10509 checkCrossUser = false;
10517 boolean providerRunning = cpr != null;
10518 if (providerRunning) {
10521 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10522 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10524 throw new SecurityException(msg);
10526 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10528 if (r != null && cpr.canRunHere(r)) {
10529 // This provider has been published or is in the process
10530 // of being published... but it is also allowed to run
10531 // in the caller's process, so don't make a connection
10532 // and just let the caller instantiate its own instance.
10533 ContentProviderHolder holder = cpr.newHolder(null);
10534 // don't give caller the provider object, it needs
10535 // to make its own.
10536 holder.provider = null;
10540 final long origId = Binder.clearCallingIdentity();
10542 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10544 // In this case the provider instance already exists, so we can
10545 // return it right away.
10546 conn = incProviderCountLocked(r, cpr, token, stable);
10547 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10548 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10549 // If this is a perceptible app accessing the provider,
10550 // make sure to count it as being accessed and thus
10551 // back up on the LRU list. This is good because
10552 // content providers are often expensive to start.
10553 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10554 updateLruProcessLocked(cpr.proc, false, null);
10555 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10559 if (cpr.proc != null) {
10560 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10561 boolean success = updateOomAdjLocked(cpr.proc);
10562 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10563 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10564 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10565 // NOTE: there is still a race here where a signal could be
10566 // pending on the process even though we managed to update its
10567 // adj level. Not sure what to do about this, but at least
10568 // the race is now smaller.
10570 // Uh oh... it looks like the provider's process
10571 // has been killed on us. We need to wait for a new
10572 // process to be started, and make sure its death
10573 // doesn't kill our process.
10574 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10575 + " is crashing; detaching " + r);
10576 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10577 checkTime(startTime, "getContentProviderImpl: before appDied");
10578 appDiedLocked(cpr.proc);
10579 checkTime(startTime, "getContentProviderImpl: after appDied");
10581 // This wasn't the last ref our process had on
10582 // the provider... we have now been killed, bail.
10585 providerRunning = false;
10590 Binder.restoreCallingIdentity(origId);
10593 if (!providerRunning) {
10595 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10596 cpi = AppGlobals.getPackageManager().
10597 resolveContentProvider(name,
10598 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10599 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10600 } catch (RemoteException ex) {
10605 // If the provider is a singleton AND
10606 // (it's a call within the same user || the provider is a
10608 // Then allow connecting to the singleton provider
10609 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10610 cpi.name, cpi.flags)
10611 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10613 userId = UserHandle.USER_SYSTEM;
10615 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10616 checkTime(startTime, "getContentProviderImpl: got app info for user");
10619 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10620 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10622 throw new SecurityException(msg);
10624 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10626 if (!mProcessesReady
10627 && !cpi.processName.equals("system")) {
10628 // If this content provider does not run in the system
10629 // process, and the system is not yet ready to run other
10630 // processes, then fail fast instead of hanging.
10631 throw new IllegalArgumentException(
10632 "Attempt to launch content provider before system ready");
10635 // Make sure that the user who owns this provider is running. If not,
10636 // we don't want to allow it to run.
10637 if (!mUserController.isUserRunningLocked(userId, 0)) {
10638 Slog.w(TAG, "Unable to launch app "
10639 + cpi.applicationInfo.packageName + "/"
10640 + cpi.applicationInfo.uid + " for provider "
10641 + name + ": user " + userId + " is stopped");
10645 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10646 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10647 cpr = mProviderMap.getProviderByClass(comp, userId);
10648 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10649 final boolean firstClass = cpr == null;
10651 final long ident = Binder.clearCallingIdentity();
10653 // If permissions need a review before any of the app components can run,
10654 // we return no provider and launch a review activity if the calling app
10655 // is in the foreground.
10656 if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10657 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10663 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10664 ApplicationInfo ai =
10665 AppGlobals.getPackageManager().
10666 getApplicationInfo(
10667 cpi.applicationInfo.packageName,
10668 STOCK_PM_FLAGS, userId);
10669 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10671 Slog.w(TAG, "No package info for content provider "
10675 ai = getAppInfoForUser(ai, userId);
10676 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10677 } catch (RemoteException ex) {
10678 // pm is in same process, this will never happen.
10680 Binder.restoreCallingIdentity(ident);
10684 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10686 if (r != null && cpr.canRunHere(r)) {
10687 // If this is a multiprocess provider, then just return its
10688 // info and allow the caller to instantiate it. Only do
10689 // this if the provider is the same user as the caller's
10690 // process, or can run as root (so can be in any process).
10691 return cpr.newHolder(null);
10694 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10695 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10696 + cpr.info.name + " callers=" + Debug.getCallers(6));
10698 // This is single process, and our app is now connecting to it.
10699 // See if we are already in the process of launching this
10701 final int N = mLaunchingProviders.size();
10703 for (i = 0; i < N; i++) {
10704 if (mLaunchingProviders.get(i) == cpr) {
10709 // If the provider is not already being launched, then get it
10712 final long origId = Binder.clearCallingIdentity();
10715 // Content provider is now in use, its package can't be stopped.
10717 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10718 AppGlobals.getPackageManager().setPackageStoppedState(
10719 cpr.appInfo.packageName, false, userId);
10720 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10721 } catch (RemoteException e) {
10722 } catch (IllegalArgumentException e) {
10723 Slog.w(TAG, "Failed trying to unstop package "
10724 + cpr.appInfo.packageName + ": " + e);
10727 // Use existing process if already started
10728 checkTime(startTime, "getContentProviderImpl: looking for process record");
10729 ProcessRecord proc = getProcessRecordLocked(
10730 cpi.processName, cpr.appInfo.uid, false);
10731 if (proc != null && proc.thread != null) {
10732 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10733 "Installing in existing process " + proc);
10734 if (!proc.pubProviders.containsKey(cpi.name)) {
10735 checkTime(startTime, "getContentProviderImpl: scheduling install");
10736 proc.pubProviders.put(cpi.name, cpr);
10738 proc.thread.scheduleInstallProvider(cpi);
10739 } catch (RemoteException e) {
10743 checkTime(startTime, "getContentProviderImpl: before start process");
10744 proc = startProcessLocked(cpi.processName,
10745 cpr.appInfo, false, 0, "content provider",
10746 new ComponentName(cpi.applicationInfo.packageName,
10747 cpi.name), false, false, false);
10748 checkTime(startTime, "getContentProviderImpl: after start process");
10749 if (proc == null) {
10750 Slog.w(TAG, "Unable to launch app "
10751 + cpi.applicationInfo.packageName + "/"
10752 + cpi.applicationInfo.uid + " for provider "
10753 + name + ": process is bad");
10757 cpr.launchingApp = proc;
10758 mLaunchingProviders.add(cpr);
10760 Binder.restoreCallingIdentity(origId);
10764 checkTime(startTime, "getContentProviderImpl: updating data structures");
10766 // Make sure the provider is published (the same provider class
10767 // may be published under multiple names).
10769 mProviderMap.putProviderByClass(comp, cpr);
10772 mProviderMap.putProviderByName(name, cpr);
10773 conn = incProviderCountLocked(r, cpr, token, stable);
10774 if (conn != null) {
10775 conn.waiting = true;
10778 checkTime(startTime, "getContentProviderImpl: done!");
10781 // Wait for the provider to be published...
10782 synchronized (cpr) {
10783 while (cpr.provider == null) {
10784 if (cpr.launchingApp == null) {
10785 Slog.w(TAG, "Unable to launch app "
10786 + cpi.applicationInfo.packageName + "/"
10787 + cpi.applicationInfo.uid + " for provider "
10788 + name + ": launching app became null");
10789 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10790 UserHandle.getUserId(cpi.applicationInfo.uid),
10791 cpi.applicationInfo.packageName,
10792 cpi.applicationInfo.uid, name);
10796 if (DEBUG_MU) Slog.v(TAG_MU,
10797 "Waiting to start provider " + cpr
10798 + " launchingApp=" + cpr.launchingApp);
10799 if (conn != null) {
10800 conn.waiting = true;
10803 } catch (InterruptedException ex) {
10805 if (conn != null) {
10806 conn.waiting = false;
10811 return cpr != null ? cpr.newHolder(conn) : null;
10814 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10815 ProcessRecord r, final int userId) {
10816 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10817 cpi.packageName, userId)) {
10819 final boolean callerForeground = r == null || r.setSchedGroup
10820 != ProcessList.SCHED_GROUP_BACKGROUND;
10822 // Show a permission review UI only for starting from a foreground app
10823 if (!callerForeground) {
10824 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10825 + cpi.packageName + " requires a permissions review");
10829 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10830 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10831 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10832 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10834 if (DEBUG_PERMISSIONS_REVIEW) {
10835 Slog.i(TAG, "u" + userId + " Launching permission review "
10836 + "for package " + cpi.packageName);
10839 final UserHandle userHandle = new UserHandle(userId);
10840 mHandler.post(new Runnable() {
10842 public void run() {
10843 mContext.startActivityAsUser(intent, userHandle);
10853 PackageManagerInternal getPackageManagerInternalLocked() {
10854 if (mPackageManagerInt == null) {
10855 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10857 return mPackageManagerInt;
10861 public final ContentProviderHolder getContentProvider(
10862 IApplicationThread caller, String name, int userId, boolean stable) {
10863 enforceNotIsolatedCaller("getContentProvider");
10864 if (caller == null) {
10865 String msg = "null IApplicationThread when getting content provider "
10868 throw new SecurityException(msg);
10870 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10871 // with cross-user grant.
10872 return getContentProviderImpl(caller, name, null, stable, userId);
10875 public ContentProviderHolder getContentProviderExternal(
10876 String name, int userId, IBinder token) {
10877 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10878 "Do not have permission in call getContentProviderExternal()");
10879 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10880 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10881 return getContentProviderExternalUnchecked(name, token, userId);
10884 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10885 IBinder token, int userId) {
10886 return getContentProviderImpl(null, name, token, true, userId);
10890 * Drop a content provider from a ProcessRecord's bookkeeping
10892 public void removeContentProvider(IBinder connection, boolean stable) {
10893 enforceNotIsolatedCaller("removeContentProvider");
10894 long ident = Binder.clearCallingIdentity();
10896 synchronized (this) {
10897 ContentProviderConnection conn;
10899 conn = (ContentProviderConnection)connection;
10900 } catch (ClassCastException e) {
10901 String msg ="removeContentProvider: " + connection
10902 + " not a ContentProviderConnection";
10904 throw new IllegalArgumentException(msg);
10906 if (conn == null) {
10907 throw new NullPointerException("connection is null");
10909 if (decProviderCountLocked(conn, null, null, stable)) {
10910 updateOomAdjLocked();
10914 Binder.restoreCallingIdentity(ident);
10918 public void removeContentProviderExternal(String name, IBinder token) {
10919 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10920 "Do not have permission in call removeContentProviderExternal()");
10921 int userId = UserHandle.getCallingUserId();
10922 long ident = Binder.clearCallingIdentity();
10924 removeContentProviderExternalUnchecked(name, token, userId);
10926 Binder.restoreCallingIdentity(ident);
10930 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10931 synchronized (this) {
10932 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10934 //remove from mProvidersByClass
10935 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10939 //update content provider record entry info
10940 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10941 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10942 if (localCpr.hasExternalProcessHandles()) {
10943 if (localCpr.removeExternalProcessHandleLocked(token)) {
10944 updateOomAdjLocked();
10946 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10947 + " with no external reference for token: "
10951 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10952 + " with no external references.");
10957 public final void publishContentProviders(IApplicationThread caller,
10958 List<ContentProviderHolder> providers) {
10959 if (providers == null) {
10963 enforceNotIsolatedCaller("publishContentProviders");
10964 synchronized (this) {
10965 final ProcessRecord r = getRecordForAppLocked(caller);
10966 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10968 throw new SecurityException(
10969 "Unable to find app for caller " + caller
10970 + " (pid=" + Binder.getCallingPid()
10971 + ") when publishing content providers");
10974 final long origId = Binder.clearCallingIdentity();
10976 final int N = providers.size();
10977 for (int i = 0; i < N; i++) {
10978 ContentProviderHolder src = providers.get(i);
10979 if (src == null || src.info == null || src.provider == null) {
10982 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10983 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10985 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10986 mProviderMap.putProviderByClass(comp, dst);
10987 String names[] = dst.info.authority.split(";");
10988 for (int j = 0; j < names.length; j++) {
10989 mProviderMap.putProviderByName(names[j], dst);
10992 int launchingCount = mLaunchingProviders.size();
10994 boolean wasInLaunchingProviders = false;
10995 for (j = 0; j < launchingCount; j++) {
10996 if (mLaunchingProviders.get(j) == dst) {
10997 mLaunchingProviders.remove(j);
10998 wasInLaunchingProviders = true;
11003 if (wasInLaunchingProviders) {
11004 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11006 synchronized (dst) {
11007 dst.provider = src.provider;
11011 updateOomAdjLocked(r);
11012 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11013 src.info.authority);
11017 Binder.restoreCallingIdentity(origId);
11021 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11022 ContentProviderConnection conn;
11024 conn = (ContentProviderConnection)connection;
11025 } catch (ClassCastException e) {
11026 String msg ="refContentProvider: " + connection
11027 + " not a ContentProviderConnection";
11029 throw new IllegalArgumentException(msg);
11031 if (conn == null) {
11032 throw new NullPointerException("connection is null");
11035 synchronized (this) {
11037 conn.numStableIncs += stable;
11039 stable = conn.stableCount + stable;
11041 throw new IllegalStateException("stableCount < 0: " + stable);
11044 if (unstable > 0) {
11045 conn.numUnstableIncs += unstable;
11047 unstable = conn.unstableCount + unstable;
11048 if (unstable < 0) {
11049 throw new IllegalStateException("unstableCount < 0: " + unstable);
11052 if ((stable+unstable) <= 0) {
11053 throw new IllegalStateException("ref counts can't go to zero here: stable="
11054 + stable + " unstable=" + unstable);
11056 conn.stableCount = stable;
11057 conn.unstableCount = unstable;
11062 public void unstableProviderDied(IBinder connection) {
11063 ContentProviderConnection conn;
11065 conn = (ContentProviderConnection)connection;
11066 } catch (ClassCastException e) {
11067 String msg ="refContentProvider: " + connection
11068 + " not a ContentProviderConnection";
11070 throw new IllegalArgumentException(msg);
11072 if (conn == null) {
11073 throw new NullPointerException("connection is null");
11076 // Safely retrieve the content provider associated with the connection.
11077 IContentProvider provider;
11078 synchronized (this) {
11079 provider = conn.provider.provider;
11082 if (provider == null) {
11083 // Um, yeah, we're way ahead of you.
11087 // Make sure the caller is being honest with us.
11088 if (provider.asBinder().pingBinder()) {
11089 // Er, no, still looks good to us.
11090 synchronized (this) {
11091 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11092 + " says " + conn + " died, but we don't agree");
11097 // Well look at that! It's dead!
11098 synchronized (this) {
11099 if (conn.provider.provider != provider) {
11100 // But something changed... good enough.
11104 ProcessRecord proc = conn.provider.proc;
11105 if (proc == null || proc.thread == null) {
11106 // Seems like the process is already cleaned up.
11110 // As far as we're concerned, this is just like receiving a
11111 // death notification... just a bit prematurely.
11112 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11113 + ") early provider death");
11114 final long ident = Binder.clearCallingIdentity();
11116 appDiedLocked(proc);
11118 Binder.restoreCallingIdentity(ident);
11124 public void appNotRespondingViaProvider(IBinder connection) {
11125 enforceCallingPermission(
11126 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11128 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11129 if (conn == null) {
11130 Slog.w(TAG, "ContentProviderConnection is null");
11134 final ProcessRecord host = conn.provider.proc;
11135 if (host == null) {
11136 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11140 mHandler.post(new Runnable() {
11142 public void run() {
11143 mAppErrors.appNotResponding(host, null, null, false,
11144 "ContentProvider not responding");
11149 public final void installSystemProviders() {
11150 List<ProviderInfo> providers;
11151 synchronized (this) {
11152 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11153 providers = generateApplicationProvidersLocked(app);
11154 if (providers != null) {
11155 for (int i=providers.size()-1; i>=0; i--) {
11156 ProviderInfo pi = (ProviderInfo)providers.get(i);
11157 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11158 Slog.w(TAG, "Not installing system proc provider " + pi.name
11159 + ": not system .apk");
11160 providers.remove(i);
11165 if (providers != null) {
11166 mSystemThread.installSystemProviders(providers);
11169 mCoreSettingsObserver = new CoreSettingsObserver(this);
11170 mFontScaleSettingObserver = new FontScaleSettingObserver();
11172 //mUsageStatsService.monitorPackages();
11175 private void startPersistentApps(int matchFlags) {
11176 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11178 synchronized (this) {
11180 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11181 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11182 for (ApplicationInfo app : apps) {
11183 if (!"android".equals(app.packageName)) {
11184 addAppLocked(app, false, null /* ABI override */);
11187 } catch (RemoteException ex) {
11193 * When a user is unlocked, we need to install encryption-unaware providers
11194 * belonging to any running apps.
11196 private void installEncryptionUnawareProviders(int userId) {
11197 // We're only interested in providers that are encryption unaware, and
11198 // we don't care about uninstalled apps, since there's no way they're
11199 // running at this point.
11200 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11202 synchronized (this) {
11203 final int NP = mProcessNames.getMap().size();
11204 for (int ip = 0; ip < NP; ip++) {
11205 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11206 final int NA = apps.size();
11207 for (int ia = 0; ia < NA; ia++) {
11208 final ProcessRecord app = apps.valueAt(ia);
11209 if (app.userId != userId || app.thread == null || app.unlocked) continue;
11211 final int NG = app.pkgList.size();
11212 for (int ig = 0; ig < NG; ig++) {
11214 final String pkgName = app.pkgList.keyAt(ig);
11215 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11216 .getPackageInfo(pkgName, matchFlags, userId);
11217 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11218 for (ProviderInfo pi : pkgInfo.providers) {
11219 // TODO: keep in sync with generateApplicationProvidersLocked
11220 final boolean processMatch = Objects.equals(pi.processName,
11221 app.processName) || pi.multiprocess;
11222 final boolean userMatch = isSingleton(pi.processName,
11223 pi.applicationInfo, pi.name, pi.flags)
11224 ? (app.userId == UserHandle.USER_SYSTEM) : true;
11225 if (processMatch && userMatch) {
11226 Log.v(TAG, "Installing " + pi);
11227 app.thread.scheduleInstallProvider(pi);
11229 Log.v(TAG, "Skipping " + pi);
11233 } catch (RemoteException ignored) {
11242 * Allows apps to retrieve the MIME type of a URI.
11243 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11244 * users, then it does not need permission to access the ContentProvider.
11245 * Either, it needs cross-user uri grants.
11247 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11249 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11250 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11252 public String getProviderMimeType(Uri uri, int userId) {
11253 enforceNotIsolatedCaller("getProviderMimeType");
11254 final String name = uri.getAuthority();
11255 int callingUid = Binder.getCallingUid();
11256 int callingPid = Binder.getCallingPid();
11258 boolean clearedIdentity = false;
11259 synchronized (this) {
11260 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11262 if (canClearIdentity(callingPid, callingUid, userId)) {
11263 clearedIdentity = true;
11264 ident = Binder.clearCallingIdentity();
11266 ContentProviderHolder holder = null;
11268 holder = getContentProviderExternalUnchecked(name, null, userId);
11269 if (holder != null) {
11270 return holder.provider.getType(uri);
11272 } catch (RemoteException e) {
11273 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11275 } catch (Exception e) {
11276 Log.w(TAG, "Exception while determining type of " + uri, e);
11279 // We need to clear the identity to call removeContentProviderExternalUnchecked
11280 if (!clearedIdentity) {
11281 ident = Binder.clearCallingIdentity();
11284 if (holder != null) {
11285 removeContentProviderExternalUnchecked(name, null, userId);
11288 Binder.restoreCallingIdentity(ident);
11295 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11296 if (UserHandle.getUserId(callingUid) == userId) {
11299 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11300 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11301 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11302 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11308 // =========================================================
11309 // GLOBAL MANAGEMENT
11310 // =========================================================
11312 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11313 boolean isolated, int isolatedUid) {
11314 String proc = customProcess != null ? customProcess : info.processName;
11315 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11316 final int userId = UserHandle.getUserId(info.uid);
11317 int uid = info.uid;
11319 if (isolatedUid == 0) {
11320 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11322 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11323 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11324 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11326 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11327 mNextIsolatedProcessUid++;
11328 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11329 // No process for this uid, use it.
11333 if (stepsLeft <= 0) {
11338 // Special case for startIsolatedProcess (internal only), where
11339 // the uid of the isolated process is specified by the caller.
11343 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11344 if (!mBooted && !mBooting
11345 && userId == UserHandle.USER_SYSTEM
11346 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11347 r.persistent = true;
11349 addProcessNameLocked(r);
11353 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11354 String abiOverride) {
11357 app = getProcessRecordLocked(info.processName, info.uid, true);
11363 app = newProcessRecordLocked(info, null, isolated, 0);
11364 updateLruProcessLocked(app, false, null);
11365 updateOomAdjLocked();
11368 // This package really, really can not be stopped.
11370 AppGlobals.getPackageManager().setPackageStoppedState(
11371 info.packageName, false, UserHandle.getUserId(app.uid));
11372 } catch (RemoteException e) {
11373 } catch (IllegalArgumentException e) {
11374 Slog.w(TAG, "Failed trying to unstop package "
11375 + info.packageName + ": " + e);
11378 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11379 app.persistent = true;
11380 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11382 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11383 mPersistentStartingProcesses.add(app);
11384 startProcessLocked(app, "added application", app.processName, abiOverride,
11385 null /* entryPoint */, null /* entryPointArgs */);
11391 public void unhandledBack() {
11392 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11393 "unhandledBack()");
11395 synchronized(this) {
11396 final long origId = Binder.clearCallingIdentity();
11398 getFocusedStack().unhandledBackLocked();
11400 Binder.restoreCallingIdentity(origId);
11405 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11406 enforceNotIsolatedCaller("openContentUri");
11407 final int userId = UserHandle.getCallingUserId();
11408 String name = uri.getAuthority();
11409 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11410 ParcelFileDescriptor pfd = null;
11412 // We record the binder invoker's uid in thread-local storage before
11413 // going to the content provider to open the file. Later, in the code
11414 // that handles all permissions checks, we look for this uid and use
11415 // that rather than the Activity Manager's own uid. The effect is that
11416 // we do the check against the caller's permissions even though it looks
11417 // to the content provider like the Activity Manager itself is making
11419 Binder token = new Binder();
11420 sCallerIdentity.set(new Identity(
11421 token, Binder.getCallingPid(), Binder.getCallingUid()));
11423 pfd = cph.provider.openFile(null, uri, "r", null, token);
11424 } catch (FileNotFoundException e) {
11425 // do nothing; pfd will be returned null
11427 // Ensure that whatever happens, we clean up the identity state
11428 sCallerIdentity.remove();
11429 // Ensure we're done with the provider.
11430 removeContentProviderExternalUnchecked(name, null, userId);
11433 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11438 // Actually is sleeping or shutting down or whatever else in the future
11439 // is an inactive state.
11440 public boolean isSleepingOrShuttingDown() {
11441 return isSleeping() || mShuttingDown;
11444 public boolean isSleeping() {
11448 void onWakefulnessChanged(int wakefulness) {
11449 synchronized(this) {
11450 mWakefulness = wakefulness;
11451 updateSleepIfNeededLocked();
11455 void finishRunningVoiceLocked() {
11456 if (mRunningVoice != null) {
11457 mRunningVoice = null;
11458 mVoiceWakeLock.release();
11459 updateSleepIfNeededLocked();
11463 void startTimeTrackingFocusedActivityLocked() {
11464 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11465 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11469 void updateSleepIfNeededLocked() {
11470 if (mSleeping && !shouldSleepLocked()) {
11472 startTimeTrackingFocusedActivityLocked();
11473 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11474 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11475 updateOomAdjLocked();
11476 } else if (!mSleeping && shouldSleepLocked()) {
11478 if (mCurAppTimeTracker != null) {
11479 mCurAppTimeTracker.stop();
11481 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11482 mStackSupervisor.goingToSleepLocked();
11483 updateOomAdjLocked();
11485 // Initialize the wake times of all processes.
11486 checkExcessivePowerUsageLocked(false);
11487 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11488 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11489 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11493 private boolean shouldSleepLocked() {
11494 // Resume applications while running a voice interactor.
11495 if (mRunningVoice != null) {
11499 // TODO: Transform the lock screen state into a sleep token instead.
11500 switch (mWakefulness) {
11501 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11502 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11503 case PowerManagerInternal.WAKEFULNESS_DOZING:
11504 // Pause applications whenever the lock screen is shown or any sleep
11505 // tokens have been acquired.
11506 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11507 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11509 // If we're asleep then pause applications unconditionally.
11514 /** Pokes the task persister. */
11515 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11516 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11519 /** Notifies all listeners when the task stack has changed. */
11520 void notifyTaskStackChangedLocked() {
11521 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11522 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11523 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11524 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11527 /** Notifies all listeners when an Activity is pinned. */
11528 void notifyActivityPinnedLocked() {
11529 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11530 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11534 * Notifies all listeners when an attempt was made to start an an activity that is already
11535 * running in the pinned stack and the activity was not actually started, but the task is
11536 * either brought to the front or a new Intent is delivered to it.
11538 void notifyPinnedActivityRestartAttemptLocked() {
11539 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11540 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11543 /** Notifies all listeners when the pinned stack animation ends. */
11545 public void notifyPinnedStackAnimationEnded() {
11546 synchronized (this) {
11547 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11548 mHandler.obtainMessage(
11549 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11554 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11555 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11559 public boolean shutdown(int timeout) {
11560 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11561 != PackageManager.PERMISSION_GRANTED) {
11562 throw new SecurityException("Requires permission "
11563 + android.Manifest.permission.SHUTDOWN);
11566 boolean timedout = false;
11568 synchronized(this) {
11569 mShuttingDown = true;
11570 updateEventDispatchingLocked();
11571 timedout = mStackSupervisor.shutdownLocked(timeout);
11574 mAppOpsService.shutdown();
11575 if (mUsageStatsService != null) {
11576 mUsageStatsService.prepareShutdown();
11578 mBatteryStatsService.shutdown();
11579 synchronized (this) {
11580 mProcessStats.shutdownLocked();
11581 notifyTaskPersisterLocked(null, true);
11587 public final void activitySlept(IBinder token) {
11588 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11590 final long origId = Binder.clearCallingIdentity();
11592 synchronized (this) {
11593 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11595 mStackSupervisor.activitySleptLocked(r);
11599 Binder.restoreCallingIdentity(origId);
11602 private String lockScreenShownToString() {
11603 switch (mLockScreenShown) {
11604 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11605 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11606 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11607 default: return "Unknown=" + mLockScreenShown;
11611 void logLockScreen(String msg) {
11612 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11613 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11614 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11615 + " mSleeping=" + mSleeping);
11618 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11619 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11620 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11621 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11622 boolean wasRunningVoice = mRunningVoice != null;
11623 mRunningVoice = session;
11624 if (!wasRunningVoice) {
11625 mVoiceWakeLock.acquire();
11626 updateSleepIfNeededLocked();
11631 private void updateEventDispatchingLocked() {
11632 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11635 public void setLockScreenShown(boolean showing, boolean occluded) {
11636 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11637 != PackageManager.PERMISSION_GRANTED) {
11638 throw new SecurityException("Requires permission "
11639 + android.Manifest.permission.DEVICE_POWER);
11642 synchronized(this) {
11643 long ident = Binder.clearCallingIdentity();
11645 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11646 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11647 if (showing && occluded) {
11648 // The lock screen is currently showing, but is occluded by a window that can
11649 // show on top of the lock screen. In this can we want to dismiss the docked
11650 // stack since it will be complicated/risky to try to put the activity on top
11651 // of the lock screen in the right fullscreen configuration.
11652 mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11653 mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11656 updateSleepIfNeededLocked();
11658 Binder.restoreCallingIdentity(ident);
11664 public void notifyLockedProfile(@UserIdInt int userId) {
11666 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11667 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11669 } catch (RemoteException ex) {
11670 throw new SecurityException("Fail to check is caller a privileged app", ex);
11673 synchronized (this) {
11674 if (mStackSupervisor.isUserLockedProfile(userId)) {
11675 final long ident = Binder.clearCallingIdentity();
11677 final int currentUserId = mUserController.getCurrentUserIdLocked();
11678 if (mUserController.isLockScreenDisabled(currentUserId)) {
11679 // If there is no device lock, we will show the profile's credential page.
11680 mActivityStarter.showConfirmDeviceCredential(userId);
11682 // Showing launcher to avoid user entering credential twice.
11683 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11686 Binder.restoreCallingIdentity(ident);
11693 public void startConfirmDeviceCredentialIntent(Intent intent) {
11694 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11695 synchronized (this) {
11696 final long ident = Binder.clearCallingIdentity();
11698 mActivityStarter.startConfirmCredentialIntent(intent);
11700 Binder.restoreCallingIdentity(ident);
11706 public void stopAppSwitches() {
11707 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11708 != PackageManager.PERMISSION_GRANTED) {
11709 throw new SecurityException("viewquires permission "
11710 + android.Manifest.permission.STOP_APP_SWITCHES);
11713 synchronized(this) {
11714 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11715 + APP_SWITCH_DELAY_TIME;
11716 mDidAppSwitch = false;
11717 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11718 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11719 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11723 public void resumeAppSwitches() {
11724 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11725 != PackageManager.PERMISSION_GRANTED) {
11726 throw new SecurityException("Requires permission "
11727 + android.Manifest.permission.STOP_APP_SWITCHES);
11730 synchronized(this) {
11731 // Note that we don't execute any pending app switches... we will
11732 // let those wait until either the timeout, or the next start
11733 // activity request.
11734 mAppSwitchesAllowedTime = 0;
11738 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11739 int callingPid, int callingUid, String name) {
11740 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11744 int perm = checkComponentPermission(
11745 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11746 sourceUid, -1, true);
11747 if (perm == PackageManager.PERMISSION_GRANTED) {
11751 // If the actual IPC caller is different from the logical source, then
11752 // also see if they are allowed to control app switches.
11753 if (callingUid != -1 && callingUid != sourceUid) {
11754 perm = checkComponentPermission(
11755 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11756 callingUid, -1, true);
11757 if (perm == PackageManager.PERMISSION_GRANTED) {
11762 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11766 public void setDebugApp(String packageName, boolean waitForDebugger,
11767 boolean persistent) {
11768 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11771 long ident = Binder.clearCallingIdentity();
11773 // Note that this is not really thread safe if there are multiple
11774 // callers into it at the same time, but that's not a situation we
11777 final ContentResolver resolver = mContext.getContentResolver();
11778 Settings.Global.putString(
11779 resolver, Settings.Global.DEBUG_APP,
11781 Settings.Global.putInt(
11782 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11783 waitForDebugger ? 1 : 0);
11786 synchronized (this) {
11788 mOrigDebugApp = mDebugApp;
11789 mOrigWaitForDebugger = mWaitForDebugger;
11791 mDebugApp = packageName;
11792 mWaitForDebugger = waitForDebugger;
11793 mDebugTransient = !persistent;
11794 if (packageName != null) {
11795 forceStopPackageLocked(packageName, -1, false, false, true, true,
11796 false, UserHandle.USER_ALL, "set debug app");
11800 Binder.restoreCallingIdentity(ident);
11804 void setTrackAllocationApp(ApplicationInfo app, String processName) {
11805 synchronized (this) {
11806 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11807 if (!isDebuggable) {
11808 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11809 throw new SecurityException("Process not debuggable: " + app.packageName);
11813 mTrackAllocationApp = processName;
11817 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11818 synchronized (this) {
11819 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11820 if (!isDebuggable) {
11821 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11822 throw new SecurityException("Process not debuggable: " + app.packageName);
11825 mProfileApp = processName;
11826 mProfileFile = profilerInfo.profileFile;
11827 if (mProfileFd != null) {
11829 mProfileFd.close();
11830 } catch (IOException e) {
11834 mProfileFd = profilerInfo.profileFd;
11835 mSamplingInterval = profilerInfo.samplingInterval;
11836 mAutoStopProfiler = profilerInfo.autoStopProfiler;
11841 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11842 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11843 if (!isDebuggable) {
11844 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11845 throw new SecurityException("Process not debuggable: " + app.packageName);
11848 mNativeDebuggingApp = processName;
11852 public void setAlwaysFinish(boolean enabled) {
11853 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11854 "setAlwaysFinish()");
11856 long ident = Binder.clearCallingIdentity();
11858 Settings.Global.putInt(
11859 mContext.getContentResolver(),
11860 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11862 synchronized (this) {
11863 mAlwaysFinishActivities = enabled;
11866 Binder.restoreCallingIdentity(ident);
11871 public void setLenientBackgroundCheck(boolean enabled) {
11872 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11873 "setLenientBackgroundCheck()");
11875 long ident = Binder.clearCallingIdentity();
11877 Settings.Global.putInt(
11878 mContext.getContentResolver(),
11879 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11881 synchronized (this) {
11882 mLenientBackgroundCheck = enabled;
11885 Binder.restoreCallingIdentity(ident);
11890 public void setActivityController(IActivityController controller, boolean imAMonkey) {
11891 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11892 "setActivityController()");
11893 synchronized (this) {
11894 mController = controller;
11895 mControllerIsAMonkey = imAMonkey;
11896 Watchdog.getInstance().setActivityController(controller);
11901 public void setUserIsMonkey(boolean userIsMonkey) {
11902 synchronized (this) {
11903 synchronized (mPidsSelfLocked) {
11904 final int callingPid = Binder.getCallingPid();
11905 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11906 if (precessRecord == null) {
11907 throw new SecurityException("Unknown process: " + callingPid);
11909 if (precessRecord.instrumentationUiAutomationConnection == null) {
11910 throw new SecurityException("Only an instrumentation process "
11911 + "with a UiAutomation can call setUserIsMonkey");
11914 mUserIsMonkey = userIsMonkey;
11919 public boolean isUserAMonkey() {
11920 synchronized (this) {
11921 // If there is a controller also implies the user is a monkey.
11922 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11926 public void requestBugReport(int bugreportType) {
11927 String service = null;
11928 switch (bugreportType) {
11929 case ActivityManager.BUGREPORT_OPTION_FULL:
11930 service = "bugreport";
11932 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11933 service = "bugreportplus";
11935 case ActivityManager.BUGREPORT_OPTION_REMOTE:
11936 service = "bugreportremote";
11939 if (service == null) {
11940 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11943 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11944 SystemProperties.set("ctl.start", service);
11947 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11948 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11951 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11952 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11953 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11955 return KEY_DISPATCHING_TIMEOUT;
11959 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11960 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11961 != PackageManager.PERMISSION_GRANTED) {
11962 throw new SecurityException("Requires permission "
11963 + android.Manifest.permission.FILTER_EVENTS);
11965 ProcessRecord proc;
11967 synchronized (this) {
11968 synchronized (mPidsSelfLocked) {
11969 proc = mPidsSelfLocked.get(pid);
11971 timeout = getInputDispatchingTimeoutLocked(proc);
11974 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11982 * Handle input dispatching timeouts.
11983 * Returns whether input dispatching should be aborted or not.
11985 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11986 final ActivityRecord activity, final ActivityRecord parent,
11987 final boolean aboveSystem, String reason) {
11988 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11989 != PackageManager.PERMISSION_GRANTED) {
11990 throw new SecurityException("Requires permission "
11991 + android.Manifest.permission.FILTER_EVENTS);
11994 final String annotation;
11995 if (reason == null) {
11996 annotation = "Input dispatching timed out";
11998 annotation = "Input dispatching timed out (" + reason + ")";
12001 if (proc != null) {
12002 synchronized (this) {
12003 if (proc.debugging) {
12008 // Give more time since we were dexopting.
12009 mDidDexOpt = false;
12013 if (proc.instrumentationClass != null) {
12014 Bundle info = new Bundle();
12015 info.putString("shortMsg", "keyDispatchingTimedOut");
12016 info.putString("longMsg", annotation);
12017 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12021 mHandler.post(new Runnable() {
12023 public void run() {
12024 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12033 public Bundle getAssistContextExtras(int requestType) {
12034 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12035 null, null, true /* focused */, true /* newSessionId */,
12036 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12040 synchronized (pae) {
12041 while (!pae.haveResult) {
12044 } catch (InterruptedException e) {
12048 synchronized (this) {
12049 buildAssistBundleLocked(pae, pae.result);
12050 mPendingAssistExtras.remove(pae);
12051 mUiHandler.removeCallbacks(pae);
12057 public boolean isAssistDataAllowedOnCurrentActivity() {
12059 synchronized (this) {
12060 userId = mUserController.getCurrentUserIdLocked();
12061 ActivityRecord activity = getFocusedStack().topActivity();
12062 if (activity == null) {
12065 userId = activity.userId;
12067 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12068 Context.DEVICE_POLICY_SERVICE);
12069 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12073 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12074 long ident = Binder.clearCallingIdentity();
12076 synchronized (this) {
12077 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12078 ActivityRecord top = getFocusedStack().topActivity();
12079 if (top != caller) {
12080 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12081 + " is not current top " + top);
12084 if (!top.nowVisible) {
12085 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12086 + " is not visible");
12090 AssistUtils utils = new AssistUtils(mContext);
12091 return utils.showSessionForActiveService(args,
12092 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12094 Binder.restoreCallingIdentity(ident);
12099 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12100 Bundle receiverExtras,
12101 IBinder activityToken, boolean focused, boolean newSessionId) {
12102 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12103 activityToken, focused, newSessionId,
12104 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12108 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12109 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12110 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12111 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12112 "enqueueAssistContext()");
12113 synchronized (this) {
12114 ActivityRecord activity = getFocusedStack().topActivity();
12115 if (activity == null) {
12116 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12119 if (activity.app == null || activity.app.thread == null) {
12120 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12124 if (activityToken != null) {
12125 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12126 if (activity != caller) {
12127 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12128 + " is not current top " + activity);
12133 activity = ActivityRecord.forTokenLocked(activityToken);
12134 if (activity == null) {
12135 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12136 + " couldn't be found");
12141 PendingAssistExtras pae;
12142 Bundle extras = new Bundle();
12143 if (args != null) {
12144 extras.putAll(args);
12146 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12147 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12148 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12150 // Increment the sessionId if necessary
12151 if (newSessionId) {
12155 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12156 requestType, mViSessionId);
12157 mPendingAssistExtras.add(pae);
12158 mUiHandler.postDelayed(pae, timeout);
12159 } catch (RemoteException e) {
12160 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12167 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12168 IResultReceiver receiver;
12169 synchronized (this) {
12170 mPendingAssistExtras.remove(pae);
12171 receiver = pae.receiver;
12173 if (receiver != null) {
12174 // Caller wants result sent back to them.
12175 Bundle sendBundle = new Bundle();
12176 // At least return the receiver extras
12177 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12178 pae.receiverExtras);
12180 pae.receiver.send(0, sendBundle);
12181 } catch (RemoteException e) {
12186 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12187 if (result != null) {
12188 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12190 if (pae.hint != null) {
12191 pae.extras.putBoolean(pae.hint, true);
12195 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12196 AssistContent content, Uri referrer) {
12197 PendingAssistExtras pae = (PendingAssistExtras)token;
12198 synchronized (pae) {
12199 pae.result = extras;
12200 pae.structure = structure;
12201 pae.content = content;
12202 if (referrer != null) {
12203 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12205 pae.haveResult = true;
12207 if (pae.intent == null && pae.receiver == null) {
12208 // Caller is just waiting for the result.
12213 // We are now ready to launch the assist activity.
12214 IResultReceiver sendReceiver = null;
12215 Bundle sendBundle = null;
12216 synchronized (this) {
12217 buildAssistBundleLocked(pae, extras);
12218 boolean exists = mPendingAssistExtras.remove(pae);
12219 mUiHandler.removeCallbacks(pae);
12224 if ((sendReceiver=pae.receiver) != null) {
12225 // Caller wants result sent back to them.
12226 sendBundle = new Bundle();
12227 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12228 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12229 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12230 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12231 pae.receiverExtras);
12234 if (sendReceiver != null) {
12236 sendReceiver.send(0, sendBundle);
12237 } catch (RemoteException e) {
12242 long ident = Binder.clearCallingIdentity();
12244 pae.intent.replaceExtras(pae.extras);
12245 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12246 | Intent.FLAG_ACTIVITY_SINGLE_TOP
12247 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12248 closeSystemDialogs("assist");
12250 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12251 } catch (ActivityNotFoundException e) {
12252 Slog.w(TAG, "No activity to handle assist action.", e);
12255 Binder.restoreCallingIdentity(ident);
12259 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12261 return enqueueAssistContext(requestType, intent, hint, null, null, null,
12262 true /* focused */, true /* newSessionId */,
12263 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12266 public void registerProcessObserver(IProcessObserver observer) {
12267 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12268 "registerProcessObserver()");
12269 synchronized (this) {
12270 mProcessObservers.register(observer);
12275 public void unregisterProcessObserver(IProcessObserver observer) {
12276 synchronized (this) {
12277 mProcessObservers.unregister(observer);
12282 public void registerUidObserver(IUidObserver observer, int which) {
12283 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12284 "registerUidObserver()");
12285 synchronized (this) {
12286 mUidObservers.register(observer, which);
12291 public void unregisterUidObserver(IUidObserver observer) {
12292 synchronized (this) {
12293 mUidObservers.unregister(observer);
12298 public boolean convertFromTranslucent(IBinder token) {
12299 final long origId = Binder.clearCallingIdentity();
12301 synchronized (this) {
12302 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12306 final boolean translucentChanged = r.changeWindowTranslucency(true);
12307 if (translucentChanged) {
12308 r.task.stack.releaseBackgroundResources(r);
12309 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12311 mWindowManager.setAppFullscreen(token, true);
12312 return translucentChanged;
12315 Binder.restoreCallingIdentity(origId);
12320 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12321 final long origId = Binder.clearCallingIdentity();
12323 synchronized (this) {
12324 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12328 int index = r.task.mActivities.lastIndexOf(r);
12330 ActivityRecord under = r.task.mActivities.get(index - 1);
12331 under.returningOptions = options;
12333 final boolean translucentChanged = r.changeWindowTranslucency(false);
12334 if (translucentChanged) {
12335 r.task.stack.convertActivityToTranslucent(r);
12337 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12338 mWindowManager.setAppFullscreen(token, false);
12339 return translucentChanged;
12342 Binder.restoreCallingIdentity(origId);
12347 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12348 final long origId = Binder.clearCallingIdentity();
12350 synchronized (this) {
12351 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12353 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12358 Binder.restoreCallingIdentity(origId);
12363 public boolean isBackgroundVisibleBehind(IBinder token) {
12364 final long origId = Binder.clearCallingIdentity();
12366 synchronized (this) {
12367 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12368 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12369 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12370 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12374 Binder.restoreCallingIdentity(origId);
12379 public ActivityOptions getActivityOptions(IBinder token) {
12380 final long origId = Binder.clearCallingIdentity();
12382 synchronized (this) {
12383 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12385 final ActivityOptions activityOptions = r.pendingOptions;
12386 r.pendingOptions = null;
12387 return activityOptions;
12392 Binder.restoreCallingIdentity(origId);
12397 public void setImmersive(IBinder token, boolean immersive) {
12398 synchronized(this) {
12399 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12401 throw new IllegalArgumentException();
12403 r.immersive = immersive;
12405 // update associated state if we're frontmost
12406 if (r == mFocusedActivity) {
12407 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12408 applyUpdateLockStateLocked(r);
12414 public boolean isImmersive(IBinder token) {
12415 synchronized (this) {
12416 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12418 throw new IllegalArgumentException();
12420 return r.immersive;
12425 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12426 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12427 throw new UnsupportedOperationException("VR mode not supported on this device!");
12430 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12433 synchronized (this) {
12434 r = ActivityRecord.isInStackLocked(token);
12438 throw new IllegalArgumentException();
12442 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12443 VrManagerInternal.NO_ERROR) {
12447 synchronized(this) {
12448 r.requestedVrComponent = (enabled) ? packageName : null;
12450 // Update associated state if this activity is currently focused
12451 if (r == mFocusedActivity) {
12452 applyUpdateVrModeLocked(r);
12459 public boolean isVrModePackageEnabled(ComponentName packageName) {
12460 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12461 throw new UnsupportedOperationException("VR mode not supported on this device!");
12464 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12466 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12467 VrManagerInternal.NO_ERROR;
12470 public boolean isTopActivityImmersive() {
12471 enforceNotIsolatedCaller("startActivity");
12472 synchronized (this) {
12473 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12474 return (r != null) ? r.immersive : false;
12479 public boolean isTopOfTask(IBinder token) {
12480 synchronized (this) {
12481 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12483 throw new IllegalArgumentException();
12485 return r.task.getTopActivity() == r;
12489 public final void enterSafeMode() {
12490 synchronized(this) {
12491 // It only makes sense to do this before the system is ready
12492 // and started launching other packages.
12493 if (!mSystemReady) {
12495 AppGlobals.getPackageManager().enterSafeMode();
12496 } catch (RemoteException e) {
12504 public final void showSafeModeOverlay() {
12505 View v = LayoutInflater.from(mContext).inflate(
12506 com.android.internal.R.layout.safe_mode, null);
12507 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12508 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12509 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12510 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12511 lp.gravity = Gravity.BOTTOM | Gravity.START;
12512 lp.format = v.getBackground().getOpacity();
12513 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12514 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12515 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12516 ((WindowManager)mContext.getSystemService(
12517 Context.WINDOW_SERVICE)).addView(v, lp);
12520 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12521 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12524 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12525 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12526 synchronized (stats) {
12527 if (mBatteryStatsService.isOnBattery()) {
12528 mBatteryStatsService.enforceCallingPermission();
12529 int MY_UID = Binder.getCallingUid();
12531 if (sender == null) {
12534 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12536 BatteryStatsImpl.Uid.Pkg pkg =
12537 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12538 sourcePkg != null ? sourcePkg : rec.key.packageName);
12539 pkg.noteWakeupAlarmLocked(tag);
12544 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12545 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12548 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12549 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12550 synchronized (stats) {
12551 mBatteryStatsService.enforceCallingPermission();
12552 int MY_UID = Binder.getCallingUid();
12554 if (sender == null) {
12557 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12559 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12563 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12564 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12567 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12568 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12569 synchronized (stats) {
12570 mBatteryStatsService.enforceCallingPermission();
12571 int MY_UID = Binder.getCallingUid();
12573 if (sender == null) {
12576 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12578 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12582 public boolean killPids(int[] pids, String pReason, boolean secure) {
12583 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12584 throw new SecurityException("killPids only available to the system");
12586 String reason = (pReason == null) ? "Unknown" : pReason;
12587 // XXX Note: don't acquire main activity lock here, because the window
12588 // manager calls in with its locks held.
12590 boolean killed = false;
12591 synchronized (mPidsSelfLocked) {
12593 for (int i=0; i<pids.length; i++) {
12594 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12595 if (proc != null) {
12596 int type = proc.setAdj;
12597 if (type > worstType) {
12603 // If the worst oom_adj is somewhere in the cached proc LRU range,
12604 // then constrain it so we will kill all cached procs.
12605 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12606 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12607 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12610 // If this is not a secure call, don't let it kill processes that
12612 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12613 worstType = ProcessList.SERVICE_ADJ;
12616 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12617 for (int i=0; i<pids.length; i++) {
12618 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12619 if (proc == null) {
12622 int adj = proc.setAdj;
12623 if (adj >= worstType && !proc.killedByAm) {
12624 proc.kill(reason, true);
12633 public void killUid(int appId, int userId, String reason) {
12634 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12635 synchronized (this) {
12636 final long identity = Binder.clearCallingIdentity();
12638 killPackageProcessesLocked(null, appId, userId,
12639 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12640 reason != null ? reason : "kill uid");
12642 Binder.restoreCallingIdentity(identity);
12648 public boolean killProcessesBelowForeground(String reason) {
12649 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12650 throw new SecurityException("killProcessesBelowForeground() only available to system");
12653 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12656 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12657 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12658 throw new SecurityException("killProcessesBelowAdj() only available to system");
12661 boolean killed = false;
12662 synchronized (mPidsSelfLocked) {
12663 final int size = mPidsSelfLocked.size();
12664 for (int i = 0; i < size; i++) {
12665 final int pid = mPidsSelfLocked.keyAt(i);
12666 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12667 if (proc == null) continue;
12669 final int adj = proc.setAdj;
12670 if (adj > belowAdj && !proc.killedByAm) {
12671 proc.kill(reason, true);
12680 public void hang(final IBinder who, boolean allowRestart) {
12681 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12682 != PackageManager.PERMISSION_GRANTED) {
12683 throw new SecurityException("Requires permission "
12684 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12687 final IBinder.DeathRecipient death = new DeathRecipient() {
12689 public void binderDied() {
12690 synchronized (this) {
12697 who.linkToDeath(death, 0);
12698 } catch (RemoteException e) {
12699 Slog.w(TAG, "hang: given caller IBinder is already dead.");
12703 synchronized (this) {
12704 Watchdog.getInstance().setAllowRestart(allowRestart);
12705 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12706 synchronized (death) {
12707 while (who.isBinderAlive()) {
12710 } catch (InterruptedException e) {
12714 Watchdog.getInstance().setAllowRestart(true);
12719 public void restart() {
12720 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12721 != PackageManager.PERMISSION_GRANTED) {
12722 throw new SecurityException("Requires permission "
12723 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12726 Log.i(TAG, "Sending shutdown broadcast...");
12728 BroadcastReceiver br = new BroadcastReceiver() {
12729 @Override public void onReceive(Context context, Intent intent) {
12730 // Now the broadcast is done, finish up the low-level shutdown.
12731 Log.i(TAG, "Shutting down activity manager...");
12733 Log.i(TAG, "Shutdown complete, restarting!");
12734 Process.killProcess(Process.myPid());
12739 // First send the high-level shut down broadcast.
12740 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12741 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12742 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12743 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12744 mContext.sendOrderedBroadcastAsUser(intent,
12745 UserHandle.ALL, null, br, mHandler, 0, null, null);
12747 br.onReceive(mContext, intent);
12750 private long getLowRamTimeSinceIdle(long now) {
12751 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12755 public void performIdleMaintenance() {
12756 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12757 != PackageManager.PERMISSION_GRANTED) {
12758 throw new SecurityException("Requires permission "
12759 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12762 synchronized (this) {
12763 final long now = SystemClock.uptimeMillis();
12764 final long timeSinceLastIdle = now - mLastIdleTime;
12765 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12766 mLastIdleTime = now;
12767 mLowRamTimeSinceLastIdle = 0;
12768 if (mLowRamStartTime != 0) {
12769 mLowRamStartTime = now;
12772 StringBuilder sb = new StringBuilder(128);
12773 sb.append("Idle maintenance over ");
12774 TimeUtils.formatDuration(timeSinceLastIdle, sb);
12775 sb.append(" low RAM for ");
12776 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12777 Slog.i(TAG, sb.toString());
12779 // If at least 1/3 of our time since the last idle period has been spent
12780 // with RAM low, then we want to kill processes.
12781 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12783 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12784 ProcessRecord proc = mLruProcesses.get(i);
12785 if (proc.notCachedSinceIdle) {
12786 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12787 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12788 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12789 if (doKilling && proc.initialIdlePss != 0
12790 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12791 sb = new StringBuilder(128);
12793 sb.append(proc.processName);
12794 sb.append(" in idle maint: pss=");
12795 sb.append(proc.lastPss);
12796 sb.append(", swapPss=");
12797 sb.append(proc.lastSwapPss);
12798 sb.append(", initialPss=");
12799 sb.append(proc.initialIdlePss);
12800 sb.append(", period=");
12801 TimeUtils.formatDuration(timeSinceLastIdle, sb);
12802 sb.append(", lowRamPeriod=");
12803 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12804 Slog.wtfQuiet(TAG, sb.toString());
12805 proc.kill("idle maint (pss " + proc.lastPss
12806 + " from " + proc.initialIdlePss + ")", true);
12809 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12810 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12811 proc.notCachedSinceIdle = true;
12812 proc.initialIdlePss = 0;
12813 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12814 mTestPssMode, isSleeping(), now);
12818 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12819 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12824 public void sendIdleJobTrigger() {
12825 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12826 != PackageManager.PERMISSION_GRANTED) {
12827 throw new SecurityException("Requires permission "
12828 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12831 final long ident = Binder.clearCallingIdentity();
12833 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
12834 .setPackage("android")
12835 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12836 broadcastIntent(null, intent, null, null, 0, null, null, null,
12837 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
12839 Binder.restoreCallingIdentity(ident);
12843 private void retrieveSettings() {
12844 final ContentResolver resolver = mContext.getContentResolver();
12845 final boolean freeformWindowManagement =
12846 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12847 || Settings.Global.getInt(
12848 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12849 final boolean supportsPictureInPicture =
12850 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12852 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12853 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12854 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12855 final boolean alwaysFinishActivities =
12856 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12857 final boolean lenientBackgroundCheck =
12858 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12859 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12860 final boolean forceResizable = Settings.Global.getInt(
12861 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12862 final boolean supportsLeanbackOnly =
12863 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
12865 // Transfer any global setting for forcing RTL layout, into a System Property
12866 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12868 final Configuration configuration = new Configuration();
12869 Settings.System.getConfiguration(resolver, configuration);
12871 // This will take care of setting the correct layout direction flags
12872 configuration.setLayoutDirection(configuration.locale);
12875 synchronized (this) {
12876 mDebugApp = mOrigDebugApp = debugApp;
12877 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12878 mAlwaysFinishActivities = alwaysFinishActivities;
12879 mLenientBackgroundCheck = lenientBackgroundCheck;
12880 mSupportsLeanbackOnly = supportsLeanbackOnly;
12881 mForceResizableActivities = forceResizable;
12882 mWindowManager.setForceResizableTasks(mForceResizableActivities);
12883 if (supportsMultiWindow || forceResizable) {
12884 mSupportsMultiWindow = true;
12885 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12886 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12888 mSupportsMultiWindow = false;
12889 mSupportsFreeformWindowManagement = false;
12890 mSupportsPictureInPicture = false;
12892 // This happens before any activities are started, so we can
12893 // change mConfiguration in-place.
12894 updateConfigurationLocked(configuration, null, true);
12895 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12896 "Initial config: " + mConfiguration);
12898 // Load resources only after the current configuration has been set.
12899 final Resources res = mContext.getResources();
12900 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12901 mThumbnailWidth = res.getDimensionPixelSize(
12902 com.android.internal.R.dimen.thumbnail_width);
12903 mThumbnailHeight = res.getDimensionPixelSize(
12904 com.android.internal.R.dimen.thumbnail_height);
12905 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12906 com.android.internal.R.string.config_defaultPictureInPictureBounds));
12907 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12908 com.android.internal.R.string.config_appsNotReportingCrashes));
12909 if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
12910 mFullscreenThumbnailScale = (float) res
12911 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
12912 (float) mConfiguration.screenWidthDp;
12914 mFullscreenThumbnailScale = res.getFraction(
12915 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
12920 public boolean testIsSystemReady() {
12921 // no need to synchronize(this) just to read & return the value
12922 return mSystemReady;
12925 public void systemReady(final Runnable goingCallback) {
12926 synchronized(this) {
12927 if (mSystemReady) {
12928 // If we're done calling all the receivers, run the next "boot phase" passed in
12929 // by the SystemServer
12930 if (goingCallback != null) {
12931 goingCallback.run();
12936 mLocalDeviceIdleController
12937 = LocalServices.getService(DeviceIdleController.LocalService.class);
12939 // Make sure we have the current profile info, since it is needed for security checks.
12940 mUserController.onSystemReady();
12941 mRecentTasks.onSystemReadyLocked();
12942 mAppOpsService.systemReady();
12943 mSystemReady = true;
12946 ArrayList<ProcessRecord> procsToKill = null;
12947 synchronized(mPidsSelfLocked) {
12948 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12949 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12950 if (!isAllowedWhileBooting(proc.info)){
12951 if (procsToKill == null) {
12952 procsToKill = new ArrayList<ProcessRecord>();
12954 procsToKill.add(proc);
12959 synchronized(this) {
12960 if (procsToKill != null) {
12961 for (int i=procsToKill.size()-1; i>=0; i--) {
12962 ProcessRecord proc = procsToKill.get(i);
12963 Slog.i(TAG, "Removing system update proc: " + proc);
12964 removeProcessLocked(proc, true, false, "system update done");
12968 // Now that we have cleaned up any update processes, we
12969 // are ready to start launching real processes and know that
12970 // we won't trample on them any more.
12971 mProcessesReady = true;
12974 Slog.i(TAG, "System now ready");
12975 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12976 SystemClock.uptimeMillis());
12978 synchronized(this) {
12979 // Make sure we have no pre-ready processes sitting around.
12981 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12982 ResolveInfo ri = mContext.getPackageManager()
12983 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12985 CharSequence errorMsg = null;
12987 ActivityInfo ai = ri.activityInfo;
12988 ApplicationInfo app = ai.applicationInfo;
12989 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12990 mTopAction = Intent.ACTION_FACTORY_TEST;
12992 mTopComponent = new ComponentName(app.packageName,
12995 errorMsg = mContext.getResources().getText(
12996 com.android.internal.R.string.factorytest_not_system);
12999 errorMsg = mContext.getResources().getText(
13000 com.android.internal.R.string.factorytest_no_action);
13002 if (errorMsg != null) {
13005 mTopComponent = null;
13006 Message msg = Message.obtain();
13007 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13008 msg.getData().putCharSequence("msg", errorMsg);
13009 mUiHandler.sendMessage(msg);
13014 retrieveSettings();
13015 final int currentUserId;
13016 synchronized (this) {
13017 currentUserId = mUserController.getCurrentUserIdLocked();
13018 readGrantedUriPermissionsLocked();
13021 if (goingCallback != null) goingCallback.run();
13023 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13024 Integer.toString(currentUserId), currentUserId);
13025 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13026 Integer.toString(currentUserId), currentUserId);
13027 mSystemServiceManager.startUser(currentUserId);
13029 synchronized (this) {
13030 // Only start up encryption-aware persistent apps; once user is
13031 // unlocked we'll come back around and start unaware apps
13032 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13034 // Start up initial activity.
13036 // Enable home activity for system user, so that the system can always boot
13037 if (UserManager.isSplitSystemUser()) {
13038 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13040 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13041 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13042 UserHandle.USER_SYSTEM);
13043 } catch (RemoteException e) {
13044 throw e.rethrowAsRuntimeException();
13047 startHomeActivityLocked(currentUserId, "systemReady");
13050 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13051 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13052 + " data partition or your device will be unstable.");
13053 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13055 } catch (RemoteException e) {
13058 if (!Build.isBuildConsistent()) {
13059 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13060 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13063 long ident = Binder.clearCallingIdentity();
13065 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13066 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13067 | Intent.FLAG_RECEIVER_FOREGROUND);
13068 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13069 broadcastIntentLocked(null, null, intent,
13070 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13071 null, false, false, MY_PID, Process.SYSTEM_UID,
13073 intent = new Intent(Intent.ACTION_USER_STARTING);
13074 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13075 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13076 broadcastIntentLocked(null, null, intent,
13077 null, new IIntentReceiver.Stub() {
13079 public void performReceive(Intent intent, int resultCode, String data,
13080 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13081 throws RemoteException {
13084 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13085 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13086 } catch (Throwable t) {
13087 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13089 Binder.restoreCallingIdentity(ident);
13091 mStackSupervisor.resumeFocusedStackTopActivityLocked();
13092 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13096 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13097 synchronized (this) {
13098 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13102 void skipCurrentReceiverLocked(ProcessRecord app) {
13103 for (BroadcastQueue queue : mBroadcastQueues) {
13104 queue.skipCurrentReceiverLocked(app);
13109 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13110 * The application process will exit immediately after this call returns.
13111 * @param app object of the crashing app, null for the system server
13112 * @param crashInfo describing the exception
13114 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13115 ProcessRecord r = findAppProcess(app, "Crash");
13116 final String processName = app == null ? "system_server"
13117 : (r == null ? "unknown" : r.processName);
13119 handleApplicationCrashInner("crash", r, processName, crashInfo);
13122 /* Native crash reporting uses this inner version because it needs to be somewhat
13123 * decoupled from the AM-managed cleanup lifecycle
13125 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13126 ApplicationErrorReport.CrashInfo crashInfo) {
13127 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13128 UserHandle.getUserId(Binder.getCallingUid()), processName,
13129 r == null ? -1 : r.info.flags,
13130 crashInfo.exceptionClassName,
13131 crashInfo.exceptionMessage,
13132 crashInfo.throwFileName,
13133 crashInfo.throwLineNumber);
13135 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13137 mAppErrors.crashApplication(r, crashInfo);
13140 public void handleApplicationStrictModeViolation(
13143 StrictMode.ViolationInfo info) {
13144 ProcessRecord r = findAppProcess(app, "StrictMode");
13149 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13150 Integer stackFingerprint = info.hashCode();
13151 boolean logIt = true;
13152 synchronized (mAlreadyLoggedViolatedStacks) {
13153 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13155 // TODO: sub-sample into EventLog for these, with
13156 // the info.durationMillis? Then we'd get
13157 // the relative pain numbers, without logging all
13158 // the stack traces repeatedly. We'd want to do
13159 // likewise in the client code, which also does
13160 // dup suppression, before the Binder call.
13162 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13163 mAlreadyLoggedViolatedStacks.clear();
13165 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13169 logStrictModeViolationToDropBox(r, info);
13173 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13174 AppErrorResult result = new AppErrorResult();
13175 synchronized (this) {
13176 final long origId = Binder.clearCallingIdentity();
13178 Message msg = Message.obtain();
13179 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13180 HashMap<String, Object> data = new HashMap<String, Object>();
13181 data.put("result", result);
13182 data.put("app", r);
13183 data.put("violationMask", violationMask);
13184 data.put("info", info);
13186 mUiHandler.sendMessage(msg);
13188 Binder.restoreCallingIdentity(origId);
13190 int res = result.get();
13191 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13195 // Depending on the policy in effect, there could be a bunch of
13196 // these in quick succession so we try to batch these together to
13197 // minimize disk writes, number of dropbox entries, and maximize
13198 // compression, by having more fewer, larger records.
13199 private void logStrictModeViolationToDropBox(
13200 ProcessRecord process,
13201 StrictMode.ViolationInfo info) {
13202 if (info == null) {
13205 final boolean isSystemApp = process == null ||
13206 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13207 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13208 final String processName = process == null ? "unknown" : process.processName;
13209 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13210 final DropBoxManager dbox = (DropBoxManager)
13211 mContext.getSystemService(Context.DROPBOX_SERVICE);
13213 // Exit early if the dropbox isn't configured to accept this report type.
13214 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13216 boolean bufferWasEmpty;
13217 boolean needsFlush;
13218 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13219 synchronized (sb) {
13220 bufferWasEmpty = sb.length() == 0;
13221 appendDropBoxProcessHeaders(process, processName, sb);
13222 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13223 sb.append("System-App: ").append(isSystemApp).append("\n");
13224 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13225 if (info.violationNumThisLoop != 0) {
13226 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13228 if (info.numAnimationsRunning != 0) {
13229 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13231 if (info.broadcastIntentAction != null) {
13232 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13234 if (info.durationMillis != -1) {
13235 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13237 if (info.numInstances != -1) {
13238 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13240 if (info.tags != null) {
13241 for (String tag : info.tags) {
13242 sb.append("Span-Tag: ").append(tag).append("\n");
13246 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13247 sb.append(info.crashInfo.stackTrace);
13250 if (info.message != null) {
13251 sb.append(info.message);
13255 // Only buffer up to ~64k. Various logging bits truncate
13257 needsFlush = (sb.length() > 64 * 1024);
13260 // Flush immediately if the buffer's grown too large, or this
13261 // is a non-system app. Non-system apps are isolated with a
13262 // different tag & policy and not batched.
13264 // Batching is useful during internal testing with
13265 // StrictMode settings turned up high. Without batching,
13266 // thousands of separate files could be created on boot.
13267 if (!isSystemApp || needsFlush) {
13268 new Thread("Error dump: " + dropboxTag) {
13270 public void run() {
13272 synchronized (sb) {
13273 report = sb.toString();
13274 sb.delete(0, sb.length());
13277 if (report.length() != 0) {
13278 dbox.addText(dropboxTag, report);
13285 // System app batching:
13286 if (!bufferWasEmpty) {
13287 // An existing dropbox-writing thread is outstanding, so
13288 // we don't need to start it up. The existing thread will
13289 // catch the buffer appends we just did.
13293 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13294 // (After this point, we shouldn't access AMS internal data structures.)
13295 new Thread("Error dump: " + dropboxTag) {
13297 public void run() {
13298 // 5 second sleep to let stacks arrive and be batched together
13300 Thread.sleep(5000); // 5 seconds
13301 } catch (InterruptedException e) {}
13303 String errorReport;
13304 synchronized (mStrictModeBuffer) {
13305 errorReport = mStrictModeBuffer.toString();
13306 if (errorReport.length() == 0) {
13309 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13310 mStrictModeBuffer.trimToSize();
13312 dbox.addText(dropboxTag, errorReport);
13318 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13319 * @param app object of the crashing app, null for the system server
13320 * @param tag reported by the caller
13321 * @param system whether this wtf is coming from the system
13322 * @param crashInfo describing the context of the error
13323 * @return true if the process should exit immediately (WTF is fatal)
13325 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13326 final ApplicationErrorReport.CrashInfo crashInfo) {
13327 final int callingUid = Binder.getCallingUid();
13328 final int callingPid = Binder.getCallingPid();
13331 // If this is coming from the system, we could very well have low-level
13332 // system locks held, so we want to do this all asynchronously. And we
13333 // never want this to become fatal, so there is that too.
13334 mHandler.post(new Runnable() {
13335 @Override public void run() {
13336 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13342 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13345 if (r != null && r.pid != Process.myPid() &&
13346 Settings.Global.getInt(mContext.getContentResolver(),
13347 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13348 mAppErrors.crashApplication(r, crashInfo);
13355 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13356 final ApplicationErrorReport.CrashInfo crashInfo) {
13357 final ProcessRecord r = findAppProcess(app, "WTF");
13358 final String processName = app == null ? "system_server"
13359 : (r == null ? "unknown" : r.processName);
13361 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13362 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13364 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13370 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13371 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13373 private ProcessRecord findAppProcess(IBinder app, String reason) {
13378 synchronized (this) {
13379 final int NP = mProcessNames.getMap().size();
13380 for (int ip=0; ip<NP; ip++) {
13381 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13382 final int NA = apps.size();
13383 for (int ia=0; ia<NA; ia++) {
13384 ProcessRecord p = apps.valueAt(ia);
13385 if (p.thread != null && p.thread.asBinder() == app) {
13391 Slog.w(TAG, "Can't find mystery application for " + reason
13392 + " from pid=" + Binder.getCallingPid()
13393 + " uid=" + Binder.getCallingUid() + ": " + app);
13399 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13400 * to append various headers to the dropbox log text.
13402 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13403 StringBuilder sb) {
13404 // Watchdog thread ends up invoking this function (with
13405 // a null ProcessRecord) to add the stack file to dropbox.
13406 // Do not acquire a lock on this (am) in such cases, as it
13407 // could cause a potential deadlock, if and when watchdog
13408 // is invoked due to unavailability of lock on am and it
13409 // would prevent watchdog from killing system_server.
13410 if (process == null) {
13411 sb.append("Process: ").append(processName).append("\n");
13414 // Note: ProcessRecord 'process' is guarded by the service
13415 // instance. (notably process.pkgList, which could otherwise change
13416 // concurrently during execution of this method)
13417 synchronized (this) {
13418 sb.append("Process: ").append(processName).append("\n");
13419 int flags = process.info.flags;
13420 IPackageManager pm = AppGlobals.getPackageManager();
13421 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13422 for (int ip=0; ip<process.pkgList.size(); ip++) {
13423 String pkg = process.pkgList.keyAt(ip);
13424 sb.append("Package: ").append(pkg);
13426 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13428 sb.append(" v").append(pi.versionCode);
13429 if (pi.versionName != null) {
13430 sb.append(" (").append(pi.versionName).append(")");
13433 } catch (RemoteException e) {
13434 Slog.e(TAG, "Error getting package info: " + pkg, e);
13441 private static String processClass(ProcessRecord process) {
13442 if (process == null || process.pid == MY_PID) {
13443 return "system_server";
13444 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13445 return "system_app";
13451 private volatile long mWtfClusterStart;
13452 private volatile int mWtfClusterCount;
13455 * Write a description of an error (crash, WTF, ANR) to the drop box.
13456 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13457 * @param process which caused the error, null means the system server
13458 * @param activity which triggered the error, null if unknown
13459 * @param parent activity related to the error, null if unknown
13460 * @param subject line related to the error, null if absent
13461 * @param report in long form describing the error, null if absent
13462 * @param logFile to include in the report, null if none
13463 * @param crashInfo giving an application stack trace, null if absent
13465 public void addErrorToDropBox(String eventType,
13466 ProcessRecord process, String processName, ActivityRecord activity,
13467 ActivityRecord parent, String subject,
13468 final String report, final File logFile,
13469 final ApplicationErrorReport.CrashInfo crashInfo) {
13470 // NOTE -- this must never acquire the ActivityManagerService lock,
13471 // otherwise the watchdog may be prevented from resetting the system.
13473 final String dropboxTag = processClass(process) + "_" + eventType;
13474 final DropBoxManager dbox = (DropBoxManager)
13475 mContext.getSystemService(Context.DROPBOX_SERVICE);
13477 // Exit early if the dropbox isn't configured to accept this report type.
13478 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13480 // Rate-limit how often we're willing to do the heavy lifting below to
13481 // collect and record logs; currently 5 logs per 10 second period.
13482 final long now = SystemClock.elapsedRealtime();
13483 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13484 mWtfClusterStart = now;
13485 mWtfClusterCount = 1;
13487 if (mWtfClusterCount++ >= 5) return;
13490 final StringBuilder sb = new StringBuilder(1024);
13491 appendDropBoxProcessHeaders(process, processName, sb);
13492 if (process != null) {
13493 sb.append("Foreground: ")
13494 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13497 if (activity != null) {
13498 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13500 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13501 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13503 if (parent != null && parent != activity) {
13504 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13506 if (subject != null) {
13507 sb.append("Subject: ").append(subject).append("\n");
13509 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13510 if (Debug.isDebuggerConnected()) {
13511 sb.append("Debugger: Connected\n");
13515 // Do the rest in a worker thread to avoid blocking the caller on I/O
13516 // (After this point, we shouldn't access AMS internal data structures.)
13517 Thread worker = new Thread("Error dump: " + dropboxTag) {
13519 public void run() {
13520 if (report != null) {
13523 if (logFile != null) {
13525 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13526 "\n\n[[TRUNCATED]]"));
13527 } catch (IOException e) {
13528 Slog.e(TAG, "Error reading " + logFile, e);
13531 if (crashInfo != null && crashInfo.stackTrace != null) {
13532 sb.append(crashInfo.stackTrace);
13535 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13536 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13540 // Merge several logcat streams, and take the last N lines
13541 InputStreamReader input = null;
13543 java.lang.Process logcat = new ProcessBuilder(
13544 "/system/bin/timeout", "-k", "15s", "10s",
13545 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13546 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13547 .redirectErrorStream(true).start();
13549 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13550 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13551 input = new InputStreamReader(logcat.getInputStream());
13554 char[] buf = new char[8192];
13555 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13556 } catch (IOException e) {
13557 Slog.e(TAG, "Error running logcat", e);
13559 if (input != null) try { input.close(); } catch (IOException e) {}
13563 dbox.addText(dropboxTag, sb.toString());
13567 if (process == null) {
13568 // If process is null, we are being called from some internal code
13569 // and may be about to die -- run this synchronously.
13577 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13578 enforceNotIsolatedCaller("getProcessesInErrorState");
13579 // assume our apps are happy - lazy create the list
13580 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13582 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13583 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13584 int userId = UserHandle.getUserId(Binder.getCallingUid());
13586 synchronized (this) {
13588 // iterate across all processes
13589 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13590 ProcessRecord app = mLruProcesses.get(i);
13591 if (!allUsers && app.userId != userId) {
13594 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13595 // This one's in trouble, so we'll generate a report for it
13596 // crashes are higher priority (in case there's a crash *and* an anr)
13597 ActivityManager.ProcessErrorStateInfo report = null;
13598 if (app.crashing) {
13599 report = app.crashingReport;
13600 } else if (app.notResponding) {
13601 report = app.notRespondingReport;
13604 if (report != null) {
13605 if (errList == null) {
13606 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13608 errList.add(report);
13610 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13611 " crashing = " + app.crashing +
13612 " notResponding = " + app.notResponding);
13621 static int procStateToImportance(int procState, int memAdj,
13622 ActivityManager.RunningAppProcessInfo currApp) {
13623 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13624 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13625 currApp.lru = memAdj;
13632 private void fillInProcMemInfo(ProcessRecord app,
13633 ActivityManager.RunningAppProcessInfo outInfo) {
13634 outInfo.pid = app.pid;
13635 outInfo.uid = app.info.uid;
13636 if (mHeavyWeightProcess == app) {
13637 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13639 if (app.persistent) {
13640 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13642 if (app.activities.size() > 0) {
13643 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13645 outInfo.lastTrimLevel = app.trimMemoryLevel;
13646 int adj = app.curAdj;
13647 int procState = app.curProcState;
13648 outInfo.importance = procStateToImportance(procState, adj, outInfo);
13649 outInfo.importanceReasonCode = app.adjTypeCode;
13650 outInfo.processState = app.curProcState;
13654 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13655 enforceNotIsolatedCaller("getRunningAppProcesses");
13657 final int callingUid = Binder.getCallingUid();
13659 // Lazy instantiation of list
13660 List<ActivityManager.RunningAppProcessInfo> runList = null;
13661 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13662 callingUid) == PackageManager.PERMISSION_GRANTED;
13663 final int userId = UserHandle.getUserId(callingUid);
13664 final boolean allUids = isGetTasksAllowed(
13665 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13667 synchronized (this) {
13668 // Iterate across all processes
13669 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13670 ProcessRecord app = mLruProcesses.get(i);
13671 if ((!allUsers && app.userId != userId)
13672 || (!allUids && app.uid != callingUid)) {
13675 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13676 // Generate process state info for running application
13677 ActivityManager.RunningAppProcessInfo currApp =
13678 new ActivityManager.RunningAppProcessInfo(app.processName,
13679 app.pid, app.getPackageList());
13680 fillInProcMemInfo(app, currApp);
13681 if (app.adjSource instanceof ProcessRecord) {
13682 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13683 currApp.importanceReasonImportance =
13684 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13685 app.adjSourceProcState);
13686 } else if (app.adjSource instanceof ActivityRecord) {
13687 ActivityRecord r = (ActivityRecord)app.adjSource;
13688 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13690 if (app.adjTarget instanceof ComponentName) {
13691 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13693 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13694 // + " lru=" + currApp.lru);
13695 if (runList == null) {
13696 runList = new ArrayList<>();
13698 runList.add(currApp);
13706 public List<ApplicationInfo> getRunningExternalApplications() {
13707 enforceNotIsolatedCaller("getRunningExternalApplications");
13708 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13709 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13710 if (runningApps != null && runningApps.size() > 0) {
13711 Set<String> extList = new HashSet<String>();
13712 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13713 if (app.pkgList != null) {
13714 for (String pkg : app.pkgList) {
13719 IPackageManager pm = AppGlobals.getPackageManager();
13720 for (String pkg : extList) {
13722 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13723 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13726 } catch (RemoteException e) {
13734 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13735 enforceNotIsolatedCaller("getMyMemoryState");
13736 synchronized (this) {
13737 ProcessRecord proc;
13738 synchronized (mPidsSelfLocked) {
13739 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13741 fillInProcMemInfo(proc, outInfo);
13746 public int getMemoryTrimLevel() {
13747 enforceNotIsolatedCaller("getMyMemoryState");
13748 synchronized (this) {
13749 return mLastMemoryLevel;
13754 public void onShellCommand(FileDescriptor in, FileDescriptor out,
13755 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13756 (new ActivityManagerShellCommand(this, false)).exec(
13757 this, in, out, err, args, resultReceiver);
13761 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13762 if (checkCallingPermission(android.Manifest.permission.DUMP)
13763 != PackageManager.PERMISSION_GRANTED) {
13764 pw.println("Permission Denial: can't dump ActivityManager from from pid="
13765 + Binder.getCallingPid()
13766 + ", uid=" + Binder.getCallingUid()
13767 + " without permission "
13768 + android.Manifest.permission.DUMP);
13772 boolean dumpAll = false;
13773 boolean dumpClient = false;
13774 String dumpPackage = null;
13777 while (opti < args.length) {
13778 String opt = args[opti];
13779 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13783 if ("-a".equals(opt)) {
13785 } else if ("-c".equals(opt)) {
13787 } else if ("-p".equals(opt)) {
13788 if (opti < args.length) {
13789 dumpPackage = args[opti];
13792 pw.println("Error: -p option requires package argument");
13796 } else if ("-h".equals(opt)) {
13797 ActivityManagerShellCommand.dumpHelp(pw, true);
13800 pw.println("Unknown argument: " + opt + "; use -h for help");
13804 long origId = Binder.clearCallingIdentity();
13805 boolean more = false;
13806 // Is the caller requesting to dump a particular piece of data?
13807 if (opti < args.length) {
13808 String cmd = args[opti];
13810 if ("activities".equals(cmd) || "a".equals(cmd)) {
13811 synchronized (this) {
13812 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13814 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13815 synchronized (this) {
13816 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13818 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13821 if (opti >= args.length) {
13823 newArgs = EMPTY_STRING_ARRAY;
13825 dumpPackage = args[opti];
13827 newArgs = new String[args.length - opti];
13828 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13829 args.length - opti);
13831 synchronized (this) {
13832 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13834 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13837 if (opti >= args.length) {
13839 newArgs = EMPTY_STRING_ARRAY;
13841 dumpPackage = args[opti];
13843 newArgs = new String[args.length - opti];
13844 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13845 args.length - opti);
13847 synchronized (this) {
13848 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13850 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13853 if (opti >= args.length) {
13855 newArgs = EMPTY_STRING_ARRAY;
13857 dumpPackage = args[opti];
13859 newArgs = new String[args.length - opti];
13860 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13861 args.length - opti);
13863 synchronized (this) {
13864 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13866 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13867 synchronized (this) {
13868 dumpOomLocked(fd, pw, args, opti, true);
13870 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13871 synchronized (this) {
13872 dumpPermissionsLocked(fd, pw, args, opti, true, null);
13874 } else if ("provider".equals(cmd)) {
13877 if (opti >= args.length) {
13879 newArgs = EMPTY_STRING_ARRAY;
13883 newArgs = new String[args.length - opti];
13884 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13886 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13887 pw.println("No providers match: " + name);
13888 pw.println("Use -h for help.");
13890 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13891 synchronized (this) {
13892 dumpProvidersLocked(fd, pw, args, opti, true, null);
13894 } else if ("service".equals(cmd)) {
13897 if (opti >= args.length) {
13899 newArgs = EMPTY_STRING_ARRAY;
13903 newArgs = new String[args.length - opti];
13904 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13905 args.length - opti);
13907 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13908 pw.println("No services match: " + name);
13909 pw.println("Use -h for help.");
13911 } else if ("package".equals(cmd)) {
13913 if (opti >= args.length) {
13914 pw.println("package: no package name specified");
13915 pw.println("Use -h for help.");
13917 dumpPackage = args[opti];
13919 newArgs = new String[args.length - opti];
13920 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13921 args.length - opti);
13926 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13927 synchronized (this) {
13928 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13930 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13932 ActiveServices.ServiceDumper dumper;
13933 synchronized (this) {
13934 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13937 dumper.dumpWithClient();
13939 synchronized (this) {
13940 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
13941 dumpPackage).dumpLocked();
13944 } else if ("locks".equals(cmd)) {
13945 LockGuard.dump(fd, pw, args);
13947 // Dumping a single activity?
13948 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13949 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13950 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13952 pw.println("Bad activity command, or no activities match: " + cmd);
13953 pw.println("Use -h for help.");
13958 Binder.restoreCallingIdentity(origId);
13963 // No piece of data specified, dump everything.
13965 ActiveServices.ServiceDumper sdumper;
13966 synchronized (this) {
13967 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13970 pw.println("-------------------------------------------------------------------------------");
13972 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13975 pw.println("-------------------------------------------------------------------------------");
13977 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13980 pw.println("-------------------------------------------------------------------------------");
13982 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13985 pw.println("-------------------------------------------------------------------------------");
13987 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
13990 sdumper.dumpWithClient();
13992 synchronized (this) {
13994 pw.println("-------------------------------------------------------------------------------");
13996 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13999 pw.println("-------------------------------------------------------------------------------");
14001 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14002 if (mAssociations.size() > 0) {
14005 pw.println("-------------------------------------------------------------------------------");
14007 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14011 pw.println("-------------------------------------------------------------------------------");
14013 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14017 synchronized (this) {
14018 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14021 pw.println("-------------------------------------------------------------------------------");
14023 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14026 pw.println("-------------------------------------------------------------------------------");
14028 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14031 pw.println("-------------------------------------------------------------------------------");
14033 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14036 pw.println("-------------------------------------------------------------------------------");
14038 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14042 pw.println("-------------------------------------------------------------------------------");
14044 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14047 pw.println("-------------------------------------------------------------------------------");
14049 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14050 if (mAssociations.size() > 0) {
14053 pw.println("-------------------------------------------------------------------------------");
14055 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14059 pw.println("-------------------------------------------------------------------------------");
14061 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14064 Binder.restoreCallingIdentity(origId);
14067 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14068 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14069 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14071 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14073 boolean needSep = printedAnything;
14075 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14076 dumpPackage, needSep, " mFocusedActivity: ");
14078 printedAnything = true;
14082 if (dumpPackage == null) {
14087 printedAnything = true;
14088 mStackSupervisor.dump(pw, " ");
14091 if (!printedAnything) {
14092 pw.println(" (nothing)");
14096 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14097 int opti, boolean dumpAll, String dumpPackage) {
14098 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14100 boolean printedAnything = false;
14102 if (mRecentTasks != null && mRecentTasks.size() > 0) {
14103 boolean printedHeader = false;
14105 final int N = mRecentTasks.size();
14106 for (int i=0; i<N; i++) {
14107 TaskRecord tr = mRecentTasks.get(i);
14108 if (dumpPackage != null) {
14109 if (tr.realActivity == null ||
14110 !dumpPackage.equals(tr.realActivity)) {
14114 if (!printedHeader) {
14115 pw.println(" Recent tasks:");
14116 printedHeader = true;
14117 printedAnything = true;
14119 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
14122 mRecentTasks.get(i).dump(pw, " ");
14127 if (!printedAnything) {
14128 pw.println(" (nothing)");
14132 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14133 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14134 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14137 if (dumpPackage != null) {
14138 IPackageManager pm = AppGlobals.getPackageManager();
14140 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14141 } catch (RemoteException e) {
14145 boolean printedAnything = false;
14147 final long now = SystemClock.uptimeMillis();
14149 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14150 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14151 = mAssociations.valueAt(i1);
14152 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14153 SparseArray<ArrayMap<String, Association>> sourceUids
14154 = targetComponents.valueAt(i2);
14155 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14156 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14157 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14158 Association ass = sourceProcesses.valueAt(i4);
14159 if (dumpPackage != null) {
14160 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14161 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14165 printedAnything = true;
14167 pw.print(ass.mTargetProcess);
14169 UserHandle.formatUid(pw, ass.mTargetUid);
14171 pw.print(ass.mSourceProcess);
14173 UserHandle.formatUid(pw, ass.mSourceUid);
14176 pw.print(ass.mTargetComponent.flattenToShortString());
14179 long dur = ass.mTime;
14180 if (ass.mNesting > 0) {
14181 dur += now - ass.mStartTime;
14183 TimeUtils.formatDuration(dur, pw);
14185 pw.print(ass.mCount);
14186 pw.print(" times)");
14188 for (int i=0; i<ass.mStateTimes.length; i++) {
14189 long amt = ass.mStateTimes[i];
14190 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14191 amt += now - ass.mLastStateUptime;
14195 pw.print(ProcessList.makeProcStateString(
14196 i + ActivityManager.MIN_PROCESS_STATE));
14198 TimeUtils.formatDuration(amt, pw);
14199 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14205 if (ass.mNesting > 0) {
14206 pw.print(" Currently active: ");
14207 TimeUtils.formatDuration(now - ass.mStartTime, pw);
14216 if (!printedAnything) {
14217 pw.println(" (nothing)");
14221 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14222 String header, boolean needSep) {
14223 boolean printed = false;
14224 int whichAppId = -1;
14225 if (dumpPackage != null) {
14227 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14229 whichAppId = UserHandle.getAppId(info.uid);
14230 } catch (NameNotFoundException e) {
14231 e.printStackTrace();
14234 for (int i=0; i<uids.size(); i++) {
14235 UidRecord uidRec = uids.valueAt(i);
14236 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14245 pw.println(header);
14248 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14249 pw.print(": "); pw.println(uidRec);
14254 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14255 int opti, boolean dumpAll, String dumpPackage) {
14256 boolean needSep = false;
14257 boolean printedAnything = false;
14260 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14263 final int NP = mProcessNames.getMap().size();
14264 for (int ip=0; ip<NP; ip++) {
14265 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14266 final int NA = procs.size();
14267 for (int ia=0; ia<NA; ia++) {
14268 ProcessRecord r = procs.valueAt(ia);
14269 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14273 pw.println(" All known processes:");
14275 printedAnything = true;
14277 pw.print(r.persistent ? " *PERS*" : " *APP*");
14278 pw.print(" UID "); pw.print(procs.keyAt(ia));
14279 pw.print(" "); pw.println(r);
14281 if (r.persistent) {
14288 if (mIsolatedProcesses.size() > 0) {
14289 boolean printed = false;
14290 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14291 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14292 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14299 pw.println(" Isolated process list (sorted by uid):");
14300 printedAnything = true;
14304 pw.println(String.format("%sIsolated #%2d: %s",
14305 " ", i, r.toString()));
14309 if (mActiveUids.size() > 0) {
14310 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14311 printedAnything = needSep = true;
14314 if (mValidateUids.size() > 0) {
14315 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14316 printedAnything = needSep = true;
14320 if (mLruProcesses.size() > 0) {
14324 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14325 pw.print(" total, non-act at ");
14326 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14327 pw.print(", non-svc at ");
14328 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14330 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14332 printedAnything = true;
14335 if (dumpAll || dumpPackage != null) {
14336 synchronized (mPidsSelfLocked) {
14337 boolean printed = false;
14338 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14339 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14340 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14344 if (needSep) pw.println();
14346 pw.println(" PID mappings:");
14348 printedAnything = true;
14350 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14351 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14356 if (mForegroundProcesses.size() > 0) {
14357 synchronized (mPidsSelfLocked) {
14358 boolean printed = false;
14359 for (int i=0; i<mForegroundProcesses.size(); i++) {
14360 ProcessRecord r = mPidsSelfLocked.get(
14361 mForegroundProcesses.valueAt(i).pid);
14362 if (dumpPackage != null && (r == null
14363 || !r.pkgList.containsKey(dumpPackage))) {
14367 if (needSep) pw.println();
14369 pw.println(" Foreground Processes:");
14371 printedAnything = true;
14373 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14374 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14379 if (mPersistentStartingProcesses.size() > 0) {
14380 if (needSep) pw.println();
14382 printedAnything = true;
14383 pw.println(" Persisent processes that are starting:");
14384 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14385 "Starting Norm", "Restarting PERS", dumpPackage);
14388 if (mRemovedProcesses.size() > 0) {
14389 if (needSep) pw.println();
14391 printedAnything = true;
14392 pw.println(" Processes that are being removed:");
14393 dumpProcessList(pw, this, mRemovedProcesses, " ",
14394 "Removed Norm", "Removed PERS", dumpPackage);
14397 if (mProcessesOnHold.size() > 0) {
14398 if (needSep) pw.println();
14400 printedAnything = true;
14401 pw.println(" Processes that are on old until the system is ready:");
14402 dumpProcessList(pw, this, mProcessesOnHold, " ",
14403 "OnHold Norm", "OnHold PERS", dumpPackage);
14406 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14408 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14410 printedAnything = true;
14413 if (dumpPackage == null) {
14416 mUserController.dump(pw, dumpAll);
14418 if (mHomeProcess != null && (dumpPackage == null
14419 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14424 pw.println(" mHomeProcess: " + mHomeProcess);
14426 if (mPreviousProcess != null && (dumpPackage == null
14427 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14432 pw.println(" mPreviousProcess: " + mPreviousProcess);
14435 StringBuilder sb = new StringBuilder(128);
14436 sb.append(" mPreviousProcessVisibleTime: ");
14437 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14440 if (mHeavyWeightProcess != null && (dumpPackage == null
14441 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14446 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14448 if (dumpPackage == null) {
14449 pw.println(" mConfiguration: " + mConfiguration);
14452 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14453 if (mCompatModePackages.getPackages().size() > 0) {
14454 boolean printed = false;
14455 for (Map.Entry<String, Integer> entry
14456 : mCompatModePackages.getPackages().entrySet()) {
14457 String pkg = entry.getKey();
14458 int mode = entry.getValue();
14459 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14463 pw.println(" mScreenCompatPackages:");
14466 pw.print(" "); pw.print(pkg); pw.print(": ");
14467 pw.print(mode); pw.println();
14471 if (dumpPackage == null) {
14472 pw.println(" mWakefulness="
14473 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14474 pw.println(" mSleepTokens=" + mSleepTokens);
14475 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14476 + lockScreenShownToString());
14477 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14478 if (mRunningVoice != null) {
14479 pw.println(" mRunningVoice=" + mRunningVoice);
14480 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14483 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14484 || mOrigWaitForDebugger) {
14485 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14486 || dumpPackage.equals(mOrigDebugApp)) {
14491 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14492 + " mDebugTransient=" + mDebugTransient
14493 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14496 if (mCurAppTimeTracker != null) {
14497 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14499 if (mMemWatchProcesses.getMap().size() > 0) {
14500 pw.println(" Mem watch processes:");
14501 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14502 = mMemWatchProcesses.getMap();
14503 for (int i=0; i<procs.size(); i++) {
14504 final String proc = procs.keyAt(i);
14505 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14506 for (int j=0; j<uids.size(); j++) {
14511 StringBuilder sb = new StringBuilder();
14512 sb.append(" ").append(proc).append('/');
14513 UserHandle.formatUid(sb, uids.keyAt(j));
14514 Pair<Long, String> val = uids.valueAt(j);
14515 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14516 if (val.second != null) {
14517 sb.append(", report to ").append(val.second);
14519 pw.println(sb.toString());
14522 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14523 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14524 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14525 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14527 if (mTrackAllocationApp != null) {
14528 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14533 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14536 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14537 || mProfileFd != null) {
14538 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14543 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14544 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14545 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14546 + mAutoStopProfiler);
14547 pw.println(" mProfileType=" + mProfileType);
14550 if (mNativeDebuggingApp != null) {
14551 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14556 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14559 if (dumpPackage == null) {
14560 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14561 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14562 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14564 if (mController != null) {
14565 pw.println(" mController=" + mController
14566 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14569 pw.println(" Total persistent processes: " + numPers);
14570 pw.println(" mProcessesReady=" + mProcessesReady
14571 + " mSystemReady=" + mSystemReady
14572 + " mBooted=" + mBooted
14573 + " mFactoryTest=" + mFactoryTest);
14574 pw.println(" mBooting=" + mBooting
14575 + " mCallFinishBooting=" + mCallFinishBooting
14576 + " mBootAnimationComplete=" + mBootAnimationComplete);
14577 pw.print(" mLastPowerCheckRealtime=");
14578 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14580 pw.print(" mLastPowerCheckUptime=");
14581 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14583 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14584 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14585 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14586 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
14587 + " (" + mLruProcesses.size() + " total)"
14588 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14589 + " mNumServiceProcs=" + mNumServiceProcs
14590 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14591 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
14592 + " mLastMemoryLevel=" + mLastMemoryLevel
14593 + " mLastNumProcesses=" + mLastNumProcesses);
14594 long now = SystemClock.uptimeMillis();
14595 pw.print(" mLastIdleTime=");
14596 TimeUtils.formatDuration(now, mLastIdleTime, pw);
14597 pw.print(" mLowRamSinceLastIdle=");
14598 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14603 if (!printedAnything) {
14604 pw.println(" (nothing)");
14608 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14609 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14610 if (mProcessesToGc.size() > 0) {
14611 boolean printed = false;
14612 long now = SystemClock.uptimeMillis();
14613 for (int i=0; i<mProcessesToGc.size(); i++) {
14614 ProcessRecord proc = mProcessesToGc.get(i);
14615 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14619 if (needSep) pw.println();
14621 pw.println(" Processes that are waiting to GC:");
14624 pw.print(" Process "); pw.println(proc);
14625 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
14626 pw.print(", last gced=");
14627 pw.print(now-proc.lastRequestedGc);
14628 pw.print(" ms ago, last lowMem=");
14629 pw.print(now-proc.lastLowMemory);
14630 pw.println(" ms ago");
14637 void printOomLevel(PrintWriter pw, String name, int adj) {
14641 if (adj < 10) pw.print(' ');
14643 if (adj > -10) pw.print(' ');
14649 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14653 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14654 int opti, boolean dumpAll) {
14655 boolean needSep = false;
14657 if (mLruProcesses.size() > 0) {
14658 if (needSep) pw.println();
14660 pw.println(" OOM levels:");
14661 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14662 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14663 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14664 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14665 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14666 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14667 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14668 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14669 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14670 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14671 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14672 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14673 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14674 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14676 if (needSep) pw.println();
14677 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
14678 pw.print(" total, non-act at ");
14679 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14680 pw.print(", non-svc at ");
14681 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14683 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
14687 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14690 pw.println(" mHomeProcess: " + mHomeProcess);
14691 pw.println(" mPreviousProcess: " + mPreviousProcess);
14692 if (mHeavyWeightProcess != null) {
14693 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14700 * There are three ways to call this:
14701 * - no provider specified: dump all the providers
14702 * - a flattened component name that matched an existing provider was specified as the
14703 * first arg: dump that one provider
14704 * - the first arg isn't the flattened component name of an existing provider:
14705 * dump all providers whose component contains the first arg as a substring
14707 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14708 int opti, boolean dumpAll) {
14709 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14712 static class ItemMatcher {
14713 ArrayList<ComponentName> components;
14714 ArrayList<String> strings;
14715 ArrayList<Integer> objects;
14722 void build(String name) {
14723 ComponentName componentName = ComponentName.unflattenFromString(name);
14724 if (componentName != null) {
14725 if (components == null) {
14726 components = new ArrayList<ComponentName>();
14728 components.add(componentName);
14732 // Not a '/' separated full component name; maybe an object ID?
14734 objectId = Integer.parseInt(name, 16);
14735 if (objects == null) {
14736 objects = new ArrayList<Integer>();
14738 objects.add(objectId);
14740 } catch (RuntimeException e) {
14741 // Not an integer; just do string match.
14742 if (strings == null) {
14743 strings = new ArrayList<String>();
14751 int build(String[] args, int opti) {
14752 for (; opti<args.length; opti++) {
14753 String name = args[opti];
14754 if ("--".equals(name)) {
14762 boolean match(Object object, ComponentName comp) {
14766 if (components != null) {
14767 for (int i=0; i<components.size(); i++) {
14768 if (components.get(i).equals(comp)) {
14773 if (objects != null) {
14774 for (int i=0; i<objects.size(); i++) {
14775 if (System.identityHashCode(object) == objects.get(i)) {
14780 if (strings != null) {
14781 String flat = comp.flattenToString();
14782 for (int i=0; i<strings.size(); i++) {
14783 if (flat.contains(strings.get(i))) {
14793 * There are three things that cmd can be:
14794 * - a flattened component name that matches an existing activity
14795 * - the cmd arg isn't the flattened component name of an existing activity:
14796 * dump all activity whose component contains the cmd as a substring
14797 * - A hex number of the ActivityRecord object instance.
14799 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14800 int opti, boolean dumpAll) {
14801 ArrayList<ActivityRecord> activities;
14803 synchronized (this) {
14804 activities = mStackSupervisor.getDumpActivitiesLocked(name);
14807 if (activities.size() <= 0) {
14811 String[] newArgs = new String[args.length - opti];
14812 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14814 TaskRecord lastTask = null;
14815 boolean needSep = false;
14816 for (int i=activities.size()-1; i>=0; i--) {
14817 ActivityRecord r = activities.get(i);
14822 synchronized (this) {
14823 if (lastTask != r.task) {
14825 pw.print("TASK "); pw.print(lastTask.affinity);
14826 pw.print(" id="); pw.println(lastTask.taskId);
14828 lastTask.dump(pw, " ");
14832 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
14838 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14839 * there is a thread associated with the activity.
14841 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14842 final ActivityRecord r, String[] args, boolean dumpAll) {
14843 String innerPrefix = prefix + " ";
14844 synchronized (this) {
14845 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14846 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14848 if (r.app != null) pw.println(r.app.pid);
14849 else pw.println("(not running)");
14851 r.dump(pw, innerPrefix);
14854 if (r.app != null && r.app.thread != null) {
14855 // flush anything that is already in the PrintWriter since the thread is going
14856 // to write to the file descriptor directly
14859 TransferPipe tp = new TransferPipe();
14861 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14862 r.appToken, innerPrefix, args);
14867 } catch (IOException e) {
14868 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14869 } catch (RemoteException e) {
14870 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14875 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14876 int opti, boolean dumpAll, String dumpPackage) {
14877 boolean needSep = false;
14878 boolean onlyHistory = false;
14879 boolean printedAnything = false;
14881 if ("history".equals(dumpPackage)) {
14882 if (opti < args.length && "-s".equals(args[opti])) {
14885 onlyHistory = true;
14886 dumpPackage = null;
14889 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14890 if (!onlyHistory && dumpAll) {
14891 if (mRegisteredReceivers.size() > 0) {
14892 boolean printed = false;
14893 Iterator it = mRegisteredReceivers.values().iterator();
14894 while (it.hasNext()) {
14895 ReceiverList r = (ReceiverList)it.next();
14896 if (dumpPackage != null && (r.app == null ||
14897 !dumpPackage.equals(r.app.info.packageName))) {
14901 pw.println(" Registered Receivers:");
14904 printedAnything = true;
14906 pw.print(" * "); pw.println(r);
14911 if (mReceiverResolver.dump(pw, needSep ?
14912 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
14913 " ", dumpPackage, false, false)) {
14915 printedAnything = true;
14919 for (BroadcastQueue q : mBroadcastQueues) {
14920 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14921 printedAnything |= needSep;
14926 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14927 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14932 printedAnything = true;
14933 pw.print(" Sticky broadcasts for user ");
14934 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14935 StringBuilder sb = new StringBuilder(128);
14936 for (Map.Entry<String, ArrayList<Intent>> ent
14937 : mStickyBroadcasts.valueAt(user).entrySet()) {
14938 pw.print(" * Sticky action "); pw.print(ent.getKey());
14941 ArrayList<Intent> intents = ent.getValue();
14942 final int N = intents.size();
14943 for (int i=0; i<N; i++) {
14945 sb.append(" Intent: ");
14946 intents.get(i).toShortString(sb, false, true, false, false);
14947 pw.println(sb.toString());
14948 Bundle bundle = intents.get(i).getExtras();
14949 if (bundle != null) {
14951 pw.println(bundle.toString());
14961 if (!onlyHistory && dumpAll) {
14963 for (BroadcastQueue queue : mBroadcastQueues) {
14964 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14965 + queue.mBroadcastsScheduled);
14967 pw.println(" mHandler:");
14968 mHandler.dump(new PrintWriterPrinter(pw), " ");
14970 printedAnything = true;
14973 if (!printedAnything) {
14974 pw.println(" (nothing)");
14978 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14979 int opti, boolean dumpAll, String dumpPackage) {
14981 boolean printedAnything = false;
14983 ItemMatcher matcher = new ItemMatcher();
14984 matcher.build(args, opti);
14986 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14988 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14989 printedAnything |= needSep;
14991 if (mLaunchingProviders.size() > 0) {
14992 boolean printed = false;
14993 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14994 ContentProviderRecord r = mLaunchingProviders.get(i);
14995 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14999 if (needSep) pw.println();
15001 pw.println(" Launching content providers:");
15003 printedAnything = true;
15005 pw.print(" Launching #"); pw.print(i); pw.print(": ");
15010 if (!printedAnything) {
15011 pw.println(" (nothing)");
15015 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15016 int opti, boolean dumpAll, String dumpPackage) {
15017 boolean needSep = false;
15018 boolean printedAnything = false;
15020 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15022 if (mGrantedUriPermissions.size() > 0) {
15023 boolean printed = false;
15025 if (dumpPackage != null) {
15027 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15028 MATCH_UNINSTALLED_PACKAGES, 0);
15029 } catch (NameNotFoundException e) {
15033 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15034 int uid = mGrantedUriPermissions.keyAt(i);
15035 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15038 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15040 if (needSep) pw.println();
15042 pw.println(" Granted Uri Permissions:");
15044 printedAnything = true;
15046 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
15047 for (UriPermission perm : perms.values()) {
15048 pw.print(" "); pw.println(perm);
15050 perm.dump(pw, " ");
15056 if (!printedAnything) {
15057 pw.println(" (nothing)");
15061 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15062 int opti, boolean dumpAll, String dumpPackage) {
15063 boolean printed = false;
15065 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15067 if (mIntentSenderRecords.size() > 0) {
15068 Iterator<WeakReference<PendingIntentRecord>> it
15069 = mIntentSenderRecords.values().iterator();
15070 while (it.hasNext()) {
15071 WeakReference<PendingIntentRecord> ref = it.next();
15072 PendingIntentRecord rec = ref != null ? ref.get(): null;
15073 if (dumpPackage != null && (rec == null
15074 || !dumpPackage.equals(rec.key.packageName))) {
15079 pw.print(" * "); pw.println(rec);
15084 pw.print(" * "); pw.println(ref);
15090 pw.println(" (nothing)");
15094 private static final int dumpProcessList(PrintWriter pw,
15095 ActivityManagerService service, List list,
15096 String prefix, String normalLabel, String persistentLabel,
15097 String dumpPackage) {
15099 final int N = list.size()-1;
15100 for (int i=N; i>=0; i--) {
15101 ProcessRecord r = (ProcessRecord)list.get(i);
15102 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15105 pw.println(String.format("%s%s #%2d: %s",
15106 prefix, (r.persistent ? persistentLabel : normalLabel),
15108 if (r.persistent) {
15115 private static final boolean dumpProcessOomList(PrintWriter pw,
15116 ActivityManagerService service, List<ProcessRecord> origList,
15117 String prefix, String normalLabel, String persistentLabel,
15118 boolean inclDetails, String dumpPackage) {
15120 ArrayList<Pair<ProcessRecord, Integer>> list
15121 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15122 for (int i=0; i<origList.size(); i++) {
15123 ProcessRecord r = origList.get(i);
15124 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15127 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15130 if (list.size() <= 0) {
15134 Comparator<Pair<ProcessRecord, Integer>> comparator
15135 = new Comparator<Pair<ProcessRecord, Integer>>() {
15137 public int compare(Pair<ProcessRecord, Integer> object1,
15138 Pair<ProcessRecord, Integer> object2) {
15139 if (object1.first.setAdj != object2.first.setAdj) {
15140 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15142 if (object1.first.setProcState != object2.first.setProcState) {
15143 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15145 if (object1.second.intValue() != object2.second.intValue()) {
15146 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15152 Collections.sort(list, comparator);
15154 final long curRealtime = SystemClock.elapsedRealtime();
15155 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15156 final long curUptime = SystemClock.uptimeMillis();
15157 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15159 for (int i=list.size()-1; i>=0; i--) {
15160 ProcessRecord r = list.get(i).first;
15161 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15163 switch (r.setSchedGroup) {
15164 case ProcessList.SCHED_GROUP_BACKGROUND:
15167 case ProcessList.SCHED_GROUP_DEFAULT:
15170 case ProcessList.SCHED_GROUP_TOP_APP:
15178 if (r.foregroundActivities) {
15180 } else if (r.foregroundServices) {
15185 String procState = ProcessList.makeProcStateString(r.curProcState);
15187 pw.print(r.persistent ? persistentLabel : normalLabel);
15189 int num = (origList.size()-1)-list.get(i).second;
15190 if (num < 10) pw.print(' ');
15195 pw.print(schedGroup);
15197 pw.print(foreground);
15199 pw.print(procState);
15201 if (r.trimMemoryLevel < 10) pw.print(' ');
15202 pw.print(r.trimMemoryLevel);
15204 pw.print(r.toShortString());
15206 pw.print(r.adjType);
15208 if (r.adjSource != null || r.adjTarget != null) {
15211 if (r.adjTarget instanceof ComponentName) {
15212 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15213 } else if (r.adjTarget != null) {
15214 pw.print(r.adjTarget.toString());
15216 pw.print("{null}");
15219 if (r.adjSource instanceof ProcessRecord) {
15221 pw.print(((ProcessRecord)r.adjSource).toShortString());
15223 } else if (r.adjSource != null) {
15224 pw.println(r.adjSource.toString());
15226 pw.println("{null}");
15232 pw.print("oom: max="); pw.print(r.maxAdj);
15233 pw.print(" curRaw="); pw.print(r.curRawAdj);
15234 pw.print(" setRaw="); pw.print(r.setRawAdj);
15235 pw.print(" cur="); pw.print(r.curAdj);
15236 pw.print(" set="); pw.println(r.setAdj);
15239 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15240 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15241 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15242 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15243 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15247 pw.print("cached="); pw.print(r.cached);
15248 pw.print(" empty="); pw.print(r.empty);
15249 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15251 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15252 if (r.lastWakeTime != 0) {
15254 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15255 synchronized (stats) {
15256 wtime = stats.getProcessWakeTime(r.info.uid,
15257 r.pid, curRealtime);
15259 long timeUsed = wtime - r.lastWakeTime;
15262 pw.print("keep awake over ");
15263 TimeUtils.formatDuration(realtimeSince, pw);
15264 pw.print(" used ");
15265 TimeUtils.formatDuration(timeUsed, pw);
15267 pw.print((timeUsed*100)/realtimeSince);
15270 if (r.lastCpuTime != 0) {
15271 long timeUsed = r.curCpuTime - r.lastCpuTime;
15274 pw.print("run cpu over ");
15275 TimeUtils.formatDuration(uptimeSince, pw);
15276 pw.print(" used ");
15277 TimeUtils.formatDuration(timeUsed, pw);
15279 pw.print((timeUsed*100)/uptimeSince);
15288 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15290 ArrayList<ProcessRecord> procs;
15291 synchronized (this) {
15292 if (args != null && args.length > start
15293 && args[start].charAt(0) != '-') {
15294 procs = new ArrayList<ProcessRecord>();
15297 pid = Integer.parseInt(args[start]);
15298 } catch (NumberFormatException e) {
15300 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15301 ProcessRecord proc = mLruProcesses.get(i);
15302 if (proc.pid == pid) {
15304 } else if (allPkgs && proc.pkgList != null
15305 && proc.pkgList.containsKey(args[start])) {
15307 } else if (proc.processName.equals(args[start])) {
15311 if (procs.size() <= 0) {
15315 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15321 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15322 PrintWriter pw, String[] args) {
15323 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15324 if (procs == null) {
15325 pw.println("No process found for: " + args[0]);
15329 long uptime = SystemClock.uptimeMillis();
15330 long realtime = SystemClock.elapsedRealtime();
15331 pw.println("Applications Graphics Acceleration Info:");
15332 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15334 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15335 ProcessRecord r = procs.get(i);
15336 if (r.thread != null) {
15337 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15340 TransferPipe tp = new TransferPipe();
15342 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15347 } catch (IOException e) {
15348 pw.println("Failure while dumping the app: " + r);
15350 } catch (RemoteException e) {
15351 pw.println("Got a RemoteException while dumping the app " + r);
15358 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15359 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15360 if (procs == null) {
15361 pw.println("No process found for: " + args[0]);
15365 pw.println("Applications Database Info:");
15367 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15368 ProcessRecord r = procs.get(i);
15369 if (r.thread != null) {
15370 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15373 TransferPipe tp = new TransferPipe();
15375 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15380 } catch (IOException e) {
15381 pw.println("Failure while dumping the app: " + r);
15383 } catch (RemoteException e) {
15384 pw.println("Got a RemoteException while dumping the app " + r);
15391 final static class MemItem {
15392 final boolean isProc;
15393 final String label;
15394 final String shortLabel;
15396 final long swapPss;
15398 final boolean hasActivities;
15399 ArrayList<MemItem> subitems;
15401 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15402 boolean _hasActivities) {
15405 shortLabel = _shortLabel;
15407 swapPss = _swapPss;
15409 hasActivities = _hasActivities;
15412 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15415 shortLabel = _shortLabel;
15417 swapPss = _swapPss;
15419 hasActivities = false;
15423 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15424 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15425 if (sort && !isCompact) {
15426 Collections.sort(items, new Comparator<MemItem>() {
15428 public int compare(MemItem lhs, MemItem rhs) {
15429 if (lhs.pss < rhs.pss) {
15431 } else if (lhs.pss > rhs.pss) {
15439 for (int i=0; i<items.size(); i++) {
15440 MemItem mi = items.get(i);
15443 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15444 mi.label, stringifyKBSize(mi.swapPss));
15446 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15448 } else if (mi.isProc) {
15449 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15450 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15451 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15452 pw.println(mi.hasActivities ? ",a" : ",e");
15454 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15455 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15457 if (mi.subitems != null) {
15458 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15459 true, isCompact, dumpSwapPss);
15464 // These are in KB.
15465 static final long[] DUMP_MEM_BUCKETS = new long[] {
15466 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15467 120*1024, 160*1024, 200*1024,
15468 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15469 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15472 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15473 boolean stackLike) {
15474 int start = label.lastIndexOf('.');
15475 if (start >= 0) start++;
15477 int end = label.length();
15478 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15479 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15480 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15481 out.append(bucket);
15482 out.append(stackLike ? "MB." : "MB ");
15483 out.append(label, start, end);
15487 out.append(memKB/1024);
15488 out.append(stackLike ? "MB." : "MB ");
15489 out.append(label, start, end);
15492 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15493 ProcessList.NATIVE_ADJ,
15494 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15495 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15496 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15497 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15498 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15499 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15501 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15503 "System", "Persistent", "Persistent Service", "Foreground",
15504 "Visible", "Perceptible",
15505 "Heavy Weight", "Backup",
15506 "A Services", "Home",
15507 "Previous", "B Services", "Cached"
15509 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15511 "sys", "pers", "persvc", "fore",
15514 "servicea", "home",
15515 "prev", "serviceb", "cached"
15518 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15519 long realtime, boolean isCheckinRequest, boolean isCompact) {
15521 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15523 if (isCheckinRequest || isCompact) {
15524 // short checkin version
15525 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15527 pw.println("Applications Memory Usage (in Kilobytes):");
15528 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15532 private static final int KSM_SHARED = 0;
15533 private static final int KSM_SHARING = 1;
15534 private static final int KSM_UNSHARED = 2;
15535 private static final int KSM_VOLATILE = 3;
15537 private final long[] getKsmInfo() {
15538 long[] longOut = new long[4];
15539 final int[] SINGLE_LONG_FORMAT = new int[] {
15540 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15542 long[] longTmp = new long[1];
15543 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15544 SINGLE_LONG_FORMAT, null, longTmp, null);
15545 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15547 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15548 SINGLE_LONG_FORMAT, null, longTmp, null);
15549 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15551 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15552 SINGLE_LONG_FORMAT, null, longTmp, null);
15553 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15555 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15556 SINGLE_LONG_FORMAT, null, longTmp, null);
15557 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15561 private static String stringifySize(long size, int order) {
15562 Locale locale = Locale.US;
15565 return String.format(locale, "%,13d", size);
15567 return String.format(locale, "%,9dK", size / 1024);
15569 return String.format(locale, "%,5dM", size / 1024 / 1024);
15570 case 1024 * 1024 * 1024:
15571 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15573 throw new IllegalArgumentException("Invalid size order");
15577 private static String stringifyKBSize(long size) {
15578 return stringifySize(size * 1024, 1024);
15581 // Update this version number in case you change the 'compact' format
15582 private static final int MEMINFO_COMPACT_VERSION = 1;
15584 final void dumpApplicationMemoryUsage(FileDescriptor fd,
15585 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15586 boolean dumpDetails = false;
15587 boolean dumpFullDetails = false;
15588 boolean dumpDalvik = false;
15589 boolean dumpSummaryOnly = false;
15590 boolean dumpUnreachable = false;
15591 boolean oomOnly = false;
15592 boolean isCompact = false;
15593 boolean localOnly = false;
15594 boolean packages = false;
15595 boolean isCheckinRequest = false;
15596 boolean dumpSwapPss = false;
15599 while (opti < args.length) {
15600 String opt = args[opti];
15601 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15605 if ("-a".equals(opt)) {
15606 dumpDetails = true;
15607 dumpFullDetails = true;
15609 dumpSwapPss = true;
15610 } else if ("-d".equals(opt)) {
15612 } else if ("-c".equals(opt)) {
15614 } else if ("-s".equals(opt)) {
15615 dumpDetails = true;
15616 dumpSummaryOnly = true;
15617 } else if ("-S".equals(opt)) {
15618 dumpSwapPss = true;
15619 } else if ("--unreachable".equals(opt)) {
15620 dumpUnreachable = true;
15621 } else if ("--oom".equals(opt)) {
15623 } else if ("--local".equals(opt)) {
15625 } else if ("--package".equals(opt)) {
15627 } else if ("--checkin".equals(opt)) {
15628 isCheckinRequest = true;
15630 } else if ("-h".equals(opt)) {
15631 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15632 pw.println(" -a: include all available information for each process.");
15633 pw.println(" -d: include dalvik details.");
15634 pw.println(" -c: dump in a compact machine-parseable representation.");
15635 pw.println(" -s: dump only summary of application memory usage.");
15636 pw.println(" -S: dump also SwapPss.");
15637 pw.println(" --oom: only show processes organized by oom adj.");
15638 pw.println(" --local: only collect details locally, don't call process.");
15639 pw.println(" --package: interpret process arg as package, dumping all");
15640 pw.println(" processes that have loaded that package.");
15641 pw.println(" --checkin: dump data for a checkin");
15642 pw.println("If [process] is specified it can be the name or ");
15643 pw.println("pid of a specific process to dump.");
15646 pw.println("Unknown argument: " + opt + "; use -h for help");
15650 long uptime = SystemClock.uptimeMillis();
15651 long realtime = SystemClock.elapsedRealtime();
15652 final long[] tmpLong = new long[1];
15654 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15655 if (procs == null) {
15656 // No Java processes. Maybe they want to print a native process.
15657 if (args != null && args.length > opti
15658 && args[opti].charAt(0) != '-') {
15659 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15660 = new ArrayList<ProcessCpuTracker.Stats>();
15661 updateCpuStatsNow();
15664 findPid = Integer.parseInt(args[opti]);
15665 } catch (NumberFormatException e) {
15667 synchronized (mProcessCpuTracker) {
15668 final int N = mProcessCpuTracker.countStats();
15669 for (int i=0; i<N; i++) {
15670 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15671 if (st.pid == findPid || (st.baseName != null
15672 && st.baseName.equals(args[opti]))) {
15673 nativeProcs.add(st);
15677 if (nativeProcs.size() > 0) {
15678 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15680 Debug.MemoryInfo mi = null;
15681 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15682 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15683 final int pid = r.pid;
15684 if (!isCheckinRequest && dumpDetails) {
15685 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15688 mi = new Debug.MemoryInfo();
15690 if (dumpDetails || (!brief && !oomOnly)) {
15691 Debug.getMemoryInfo(pid, mi);
15693 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15694 mi.dalvikPrivateDirty = (int)tmpLong[0];
15696 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15697 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15698 if (isCheckinRequest) {
15705 pw.println("No process found for: " + args[opti]);
15709 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15710 dumpDetails = true;
15713 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15715 String[] innerArgs = new String[args.length-opti];
15716 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15718 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15719 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15720 long nativePss = 0;
15721 long nativeSwapPss = 0;
15722 long dalvikPss = 0;
15723 long dalvikSwapPss = 0;
15724 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15726 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15729 long otherSwapPss = 0;
15730 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15731 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15733 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15734 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15735 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15736 new ArrayList[DUMP_MEM_OOM_LABEL.length];
15739 long totalSwapPss = 0;
15740 long cachedPss = 0;
15741 long cachedSwapPss = 0;
15742 boolean hasSwapPss = false;
15744 Debug.MemoryInfo mi = null;
15745 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15746 final ProcessRecord r = procs.get(i);
15747 final IApplicationThread thread;
15750 final boolean hasActivities;
15751 synchronized (this) {
15754 oomAdj = r.getSetAdjWithServices();
15755 hasActivities = r.activities.size() > 0;
15757 if (thread != null) {
15758 if (!isCheckinRequest && dumpDetails) {
15759 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15762 mi = new Debug.MemoryInfo();
15764 if (dumpDetails || (!brief && !oomOnly)) {
15765 Debug.getMemoryInfo(pid, mi);
15766 hasSwapPss = mi.hasSwappedOutPss;
15768 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15769 mi.dalvikPrivateDirty = (int)tmpLong[0];
15773 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15774 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15775 if (isCheckinRequest) {
15781 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15782 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15783 } catch (RemoteException e) {
15784 if (!isCheckinRequest) {
15785 pw.println("Got RemoteException!");
15792 final long myTotalPss = mi.getTotalPss();
15793 final long myTotalUss = mi.getTotalUss();
15794 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15796 synchronized (this) {
15797 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15798 // Record this for posterity if the process has been stable.
15799 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15803 if (!isCheckinRequest && mi != null) {
15804 totalPss += myTotalPss;
15805 totalSwapPss += myTotalSwapPss;
15806 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15807 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15808 myTotalSwapPss, pid, hasActivities);
15809 procMems.add(pssItem);
15810 procMemsMap.put(pid, pssItem);
15812 nativePss += mi.nativePss;
15813 nativeSwapPss += mi.nativeSwappedOutPss;
15814 dalvikPss += mi.dalvikPss;
15815 dalvikSwapPss += mi.dalvikSwappedOutPss;
15816 for (int j=0; j<dalvikSubitemPss.length; j++) {
15817 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15818 dalvikSubitemSwapPss[j] +=
15819 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15821 otherPss += mi.otherPss;
15822 otherSwapPss += mi.otherSwappedOutPss;
15823 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15824 long mem = mi.getOtherPss(j);
15827 mem = mi.getOtherSwappedOutPss(j);
15828 miscSwapPss[j] += mem;
15829 otherSwapPss -= mem;
15832 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15833 cachedPss += myTotalPss;
15834 cachedSwapPss += myTotalSwapPss;
15837 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15838 if (oomIndex == (oomPss.length - 1)
15839 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
15840 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
15841 oomPss[oomIndex] += myTotalPss;
15842 oomSwapPss[oomIndex] += myTotalSwapPss;
15843 if (oomProcs[oomIndex] == null) {
15844 oomProcs[oomIndex] = new ArrayList<MemItem>();
15846 oomProcs[oomIndex].add(pssItem);
15854 long nativeProcTotalPss = 0;
15856 if (!isCheckinRequest && procs.size() > 1 && !packages) {
15857 // If we are showing aggregations, also look for native processes to
15858 // include so that our aggregations are more accurate.
15859 updateCpuStatsNow();
15861 synchronized (mProcessCpuTracker) {
15862 final int N = mProcessCpuTracker.countStats();
15863 for (int i=0; i<N; i++) {
15864 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15865 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15867 mi = new Debug.MemoryInfo();
15869 if (!brief && !oomOnly) {
15870 Debug.getMemoryInfo(st.pid, mi);
15872 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15873 mi.nativePrivateDirty = (int)tmpLong[0];
15876 final long myTotalPss = mi.getTotalPss();
15877 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15878 totalPss += myTotalPss;
15879 nativeProcTotalPss += myTotalPss;
15881 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15882 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15883 procMems.add(pssItem);
15885 nativePss += mi.nativePss;
15886 nativeSwapPss += mi.nativeSwappedOutPss;
15887 dalvikPss += mi.dalvikPss;
15888 dalvikSwapPss += mi.dalvikSwappedOutPss;
15889 for (int j=0; j<dalvikSubitemPss.length; j++) {
15890 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15891 dalvikSubitemSwapPss[j] +=
15892 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15894 otherPss += mi.otherPss;
15895 otherSwapPss += mi.otherSwappedOutPss;
15896 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15897 long mem = mi.getOtherPss(j);
15900 mem = mi.getOtherSwappedOutPss(j);
15901 miscSwapPss[j] += mem;
15902 otherSwapPss -= mem;
15904 oomPss[0] += myTotalPss;
15905 oomSwapPss[0] += myTotalSwapPss;
15906 if (oomProcs[0] == null) {
15907 oomProcs[0] = new ArrayList<MemItem>();
15909 oomProcs[0].add(pssItem);
15914 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15916 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15917 final MemItem dalvikItem =
15918 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15919 if (dalvikSubitemPss.length > 0) {
15920 dalvikItem.subitems = new ArrayList<MemItem>();
15921 for (int j=0; j<dalvikSubitemPss.length; j++) {
15922 final String name = Debug.MemoryInfo.getOtherLabel(
15923 Debug.MemoryInfo.NUM_OTHER_STATS + j);
15924 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15925 dalvikSubitemSwapPss[j], j));
15928 catMems.add(dalvikItem);
15929 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15930 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15931 String label = Debug.MemoryInfo.getOtherLabel(j);
15932 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15935 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15936 for (int j=0; j<oomPss.length; j++) {
15937 if (oomPss[j] != 0) {
15938 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15939 : DUMP_MEM_OOM_LABEL[j];
15940 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15941 DUMP_MEM_OOM_ADJ[j]);
15942 item.subitems = oomProcs[j];
15947 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15948 if (!brief && !oomOnly && !isCompact) {
15950 pw.println("Total PSS by process:");
15951 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
15955 pw.println("Total PSS by OOM adjustment:");
15957 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
15958 if (!brief && !oomOnly) {
15959 PrintWriter out = categoryPw != null ? categoryPw : pw;
15962 out.println("Total PSS by category:");
15964 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
15969 MemInfoReader memInfo = new MemInfoReader();
15970 memInfo.readMemInfo();
15971 if (nativeProcTotalPss > 0) {
15972 synchronized (this) {
15973 final long cachedKb = memInfo.getCachedSizeKb();
15974 final long freeKb = memInfo.getFreeSizeKb();
15975 final long zramKb = memInfo.getZramTotalSizeKb();
15976 final long kernelKb = memInfo.getKernelUsedSizeKb();
15977 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15978 kernelKb*1024, nativeProcTotalPss*1024);
15979 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15980 nativeProcTotalPss);
15985 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15986 pw.print(" (status ");
15987 switch (mLastMemoryLevel) {
15988 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15989 pw.println("normal)");
15991 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15992 pw.println("moderate)");
15994 case ProcessStats.ADJ_MEM_FACTOR_LOW:
15995 pw.println("low)");
15997 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15998 pw.println("critical)");
16001 pw.print(mLastMemoryLevel);
16005 pw.print(" Free RAM: ");
16006 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16007 + memInfo.getFreeSizeKb()));
16009 pw.print(stringifyKBSize(cachedPss));
16010 pw.print(" cached pss + ");
16011 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16012 pw.print(" cached kernel + ");
16013 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16014 pw.println(" free)");
16016 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16017 pw.print(cachedPss + memInfo.getCachedSizeKb()
16018 + memInfo.getFreeSizeKb()); pw.print(",");
16019 pw.println(totalPss - cachedPss);
16022 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16023 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16024 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16026 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16027 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16028 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16029 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16030 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16032 pw.print("lostram,"); pw.println(lostRAM);
16035 if (memInfo.getZramTotalSizeKb() != 0) {
16037 pw.print(" ZRAM: ");
16038 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16039 pw.print(" physical used for ");
16040 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16041 - memInfo.getSwapFreeSizeKb()));
16042 pw.print(" in swap (");
16043 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16044 pw.println(" total swap)");
16046 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16047 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16048 pw.println(memInfo.getSwapFreeSizeKb());
16051 final long[] ksm = getKsmInfo();
16053 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16054 || ksm[KSM_VOLATILE] != 0) {
16055 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16056 pw.print(" saved from shared ");
16057 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16058 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16059 pw.print(" unshared; ");
16060 pw.print(stringifyKBSize(
16061 ksm[KSM_VOLATILE])); pw.println(" volatile");
16063 pw.print(" Tuning: ");
16064 pw.print(ActivityManager.staticGetMemoryClass());
16065 pw.print(" (large ");
16066 pw.print(ActivityManager.staticGetLargeMemoryClass());
16067 pw.print("), oom ");
16068 pw.print(stringifySize(
16069 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16070 pw.print(", restore limit ");
16071 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16072 if (ActivityManager.isLowRamDeviceStatic()) {
16073 pw.print(" (low-ram)");
16075 if (ActivityManager.isHighEndGfx()) {
16076 pw.print(" (high-end-gfx)");
16080 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16081 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16082 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16083 pw.print("tuning,");
16084 pw.print(ActivityManager.staticGetMemoryClass());
16086 pw.print(ActivityManager.staticGetLargeMemoryClass());
16088 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16089 if (ActivityManager.isLowRamDeviceStatic()) {
16090 pw.print(",low-ram");
16092 if (ActivityManager.isHighEndGfx()) {
16093 pw.print(",high-end-gfx");
16101 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16102 long memtrack, String name) {
16104 sb.append(ProcessList.makeOomAdjString(oomAdj));
16106 sb.append(ProcessList.makeProcStateString(procState));
16108 ProcessList.appendRamKb(sb, pss);
16111 if (memtrack > 0) {
16113 sb.append(stringifyKBSize(memtrack));
16114 sb.append(" memtrack)");
16118 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16119 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16120 sb.append(" (pid ");
16123 sb.append(mi.adjType);
16125 if (mi.adjReason != null) {
16127 sb.append(mi.adjReason);
16132 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16133 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16134 for (int i=0, N=memInfos.size(); i<N; i++) {
16135 ProcessMemInfo mi = memInfos.get(i);
16136 infoMap.put(mi.pid, mi);
16138 updateCpuStatsNow();
16139 long[] memtrackTmp = new long[1];
16140 synchronized (mProcessCpuTracker) {
16141 final int N = mProcessCpuTracker.countStats();
16142 for (int i=0; i<N; i++) {
16143 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16144 if (st.vsize > 0) {
16145 long pss = Debug.getPss(st.pid, null, memtrackTmp);
16147 if (infoMap.indexOfKey(st.pid) < 0) {
16148 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16149 ProcessList.NATIVE_ADJ, -1, "native", null);
16151 mi.memtrack = memtrackTmp[0];
16160 long totalMemtrack = 0;
16161 for (int i=0, N=memInfos.size(); i<N; i++) {
16162 ProcessMemInfo mi = memInfos.get(i);
16164 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16165 mi.memtrack = memtrackTmp[0];
16167 totalPss += mi.pss;
16168 totalMemtrack += mi.memtrack;
16170 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16171 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16172 if (lhs.oomAdj != rhs.oomAdj) {
16173 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16175 if (lhs.pss != rhs.pss) {
16176 return lhs.pss < rhs.pss ? 1 : -1;
16182 StringBuilder tag = new StringBuilder(128);
16183 StringBuilder stack = new StringBuilder(128);
16184 tag.append("Low on memory -- ");
16185 appendMemBucket(tag, totalPss, "total", false);
16186 appendMemBucket(stack, totalPss, "total", true);
16188 StringBuilder fullNativeBuilder = new StringBuilder(1024);
16189 StringBuilder shortNativeBuilder = new StringBuilder(1024);
16190 StringBuilder fullJavaBuilder = new StringBuilder(1024);
16192 boolean firstLine = true;
16193 int lastOomAdj = Integer.MIN_VALUE;
16194 long extraNativeRam = 0;
16195 long extraNativeMemtrack = 0;
16196 long cachedPss = 0;
16197 for (int i=0, N=memInfos.size(); i<N; i++) {
16198 ProcessMemInfo mi = memInfos.get(i);
16200 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16201 cachedPss += mi.pss;
16204 if (mi.oomAdj != ProcessList.NATIVE_ADJ
16205 && (mi.oomAdj < ProcessList.SERVICE_ADJ
16206 || mi.oomAdj == ProcessList.HOME_APP_ADJ
16207 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16208 if (lastOomAdj != mi.oomAdj) {
16209 lastOomAdj = mi.oomAdj;
16210 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16213 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16218 stack.append("\n\t at ");
16226 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16227 appendMemBucket(tag, mi.pss, mi.name, false);
16229 appendMemBucket(stack, mi.pss, mi.name, true);
16230 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16231 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16233 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16234 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16235 stack.append(DUMP_MEM_OOM_LABEL[k]);
16237 stack.append(DUMP_MEM_OOM_ADJ[k]);
16244 appendMemInfo(fullNativeBuilder, mi);
16245 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16246 // The short form only has native processes that are >= 512K.
16247 if (mi.pss >= 512) {
16248 appendMemInfo(shortNativeBuilder, mi);
16250 extraNativeRam += mi.pss;
16251 extraNativeMemtrack += mi.memtrack;
16254 // Short form has all other details, but if we have collected RAM
16255 // from smaller native processes let's dump a summary of that.
16256 if (extraNativeRam > 0) {
16257 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16258 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16259 shortNativeBuilder.append('\n');
16260 extraNativeRam = 0;
16262 appendMemInfo(fullJavaBuilder, mi);
16266 fullJavaBuilder.append(" ");
16267 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16268 fullJavaBuilder.append(": TOTAL");
16269 if (totalMemtrack > 0) {
16270 fullJavaBuilder.append(" (");
16271 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16272 fullJavaBuilder.append(" memtrack)");
16275 fullJavaBuilder.append("\n");
16277 MemInfoReader memInfo = new MemInfoReader();
16278 memInfo.readMemInfo();
16279 final long[] infos = memInfo.getRawInfo();
16281 StringBuilder memInfoBuilder = new StringBuilder(1024);
16282 Debug.getMemInfo(infos);
16283 memInfoBuilder.append(" MemInfo: ");
16284 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16285 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16286 memInfoBuilder.append(stringifyKBSize(
16287 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16288 memInfoBuilder.append(stringifyKBSize(
16289 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16290 memInfoBuilder.append(stringifyKBSize(
16291 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16292 memInfoBuilder.append(" ");
16293 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16294 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16295 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16296 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16297 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16298 memInfoBuilder.append(" ZRAM: ");
16299 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16300 memInfoBuilder.append(" RAM, ");
16301 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16302 memInfoBuilder.append(" swap total, ");
16303 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16304 memInfoBuilder.append(" swap free\n");
16306 final long[] ksm = getKsmInfo();
16307 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16308 || ksm[KSM_VOLATILE] != 0) {
16309 memInfoBuilder.append(" KSM: ");
16310 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16311 memInfoBuilder.append(" saved from shared ");
16312 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16313 memInfoBuilder.append("\n ");
16314 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16315 memInfoBuilder.append(" unshared; ");
16316 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16317 memInfoBuilder.append(" volatile\n");
16319 memInfoBuilder.append(" Free RAM: ");
16320 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16321 + memInfo.getFreeSizeKb()));
16322 memInfoBuilder.append("\n");
16323 memInfoBuilder.append(" Used RAM: ");
16324 memInfoBuilder.append(stringifyKBSize(
16325 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16326 memInfoBuilder.append("\n");
16327 memInfoBuilder.append(" Lost RAM: ");
16328 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16329 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16330 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16331 memInfoBuilder.append("\n");
16332 Slog.i(TAG, "Low on memory:");
16333 Slog.i(TAG, shortNativeBuilder.toString());
16334 Slog.i(TAG, fullJavaBuilder.toString());
16335 Slog.i(TAG, memInfoBuilder.toString());
16337 StringBuilder dropBuilder = new StringBuilder(1024);
16339 StringWriter oomSw = new StringWriter();
16340 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16341 StringWriter catSw = new StringWriter();
16342 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16343 String[] emptyArgs = new String[] { };
16344 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16346 String oomString = oomSw.toString();
16348 dropBuilder.append("Low on memory:");
16349 dropBuilder.append(stack);
16350 dropBuilder.append('\n');
16351 dropBuilder.append(fullNativeBuilder);
16352 dropBuilder.append(fullJavaBuilder);
16353 dropBuilder.append('\n');
16354 dropBuilder.append(memInfoBuilder);
16355 dropBuilder.append('\n');
16357 dropBuilder.append(oomString);
16358 dropBuilder.append('\n');
16360 StringWriter catSw = new StringWriter();
16361 synchronized (ActivityManagerService.this) {
16362 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16363 String[] emptyArgs = new String[] { };
16365 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16367 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16368 false, null).dumpLocked();
16370 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16373 dropBuilder.append(catSw.toString());
16374 addErrorToDropBox("lowmem", null, "system_server", null,
16375 null, tag.toString(), dropBuilder.toString(), null, null);
16376 //Slog.i(TAG, "Sent to dropbox:");
16377 //Slog.i(TAG, dropBuilder.toString());
16378 synchronized (ActivityManagerService.this) {
16379 long now = SystemClock.uptimeMillis();
16380 if (mLastMemUsageReportTime < now) {
16381 mLastMemUsageReportTime = now;
16387 * Searches array of arguments for the specified string
16388 * @param args array of argument strings
16389 * @param value value to search for
16390 * @return true if the value is contained in the array
16392 private static boolean scanArgs(String[] args, String value) {
16393 if (args != null) {
16394 for (String arg : args) {
16395 if (value.equals(arg)) {
16403 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16404 ContentProviderRecord cpr, boolean always) {
16405 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16407 if (!inLaunching || always) {
16408 synchronized (cpr) {
16409 cpr.launchingApp = null;
16412 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16413 String names[] = cpr.info.authority.split(";");
16414 for (int j = 0; j < names.length; j++) {
16415 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16419 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16420 ContentProviderConnection conn = cpr.connections.get(i);
16421 if (conn.waiting) {
16422 // If this connection is waiting for the provider, then we don't
16423 // need to mess with its process unless we are always removing
16424 // or for some reason the provider is not currently launching.
16425 if (inLaunching && !always) {
16429 ProcessRecord capp = conn.client;
16431 if (conn.stableCount > 0) {
16432 if (!capp.persistent && capp.thread != null
16434 && capp.pid != MY_PID) {
16435 capp.kill("depends on provider "
16436 + cpr.name.flattenToShortString()
16437 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16439 } else if (capp.thread != null && conn.provider.provider != null) {
16441 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16442 } catch (RemoteException e) {
16444 // In the protocol here, we don't expect the client to correctly
16445 // clean up this connection, we'll just remove it.
16446 cpr.connections.remove(i);
16447 if (conn.client.conProviders.remove(conn)) {
16448 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16453 if (inLaunching && always) {
16454 mLaunchingProviders.remove(cpr);
16456 return inLaunching;
16460 * Main code for cleaning up a process when it has gone away. This is
16461 * called both as a result of the process dying, or directly when stopping
16462 * a process when running in single process mode.
16464 * @return Returns true if the given process has been restarted, so the
16465 * app that was passed in must remain on the process lists.
16467 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16468 boolean restarting, boolean allowRestart, int index) {
16470 removeLruProcessLocked(app);
16471 ProcessList.remove(app.pid);
16474 mProcessesToGc.remove(app);
16475 mPendingPssProcesses.remove(app);
16477 // Dismiss any open dialogs.
16478 if (app.crashDialog != null && !app.forceCrashReport) {
16479 app.crashDialog.dismiss();
16480 app.crashDialog = null;
16482 if (app.anrDialog != null) {
16483 app.anrDialog.dismiss();
16484 app.anrDialog = null;
16486 if (app.waitDialog != null) {
16487 app.waitDialog.dismiss();
16488 app.waitDialog = null;
16491 app.crashing = false;
16492 app.notResponding = false;
16494 app.resetPackageList(mProcessStats);
16495 app.unlinkDeathRecipient();
16496 app.makeInactive(mProcessStats);
16497 app.waitingToKill = null;
16498 app.forcingToForeground = null;
16499 updateProcessForegroundLocked(app, false, false);
16500 app.foregroundActivities = false;
16501 app.hasShownUi = false;
16502 app.treatLikeActivity = false;
16503 app.hasAboveClient = false;
16504 app.hasClientActivities = false;
16506 mServices.killServicesLocked(app, allowRestart);
16508 boolean restart = false;
16510 // Remove published content providers.
16511 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16512 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16513 final boolean always = app.bad || !allowRestart;
16514 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16515 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16516 // We left the provider in the launching list, need to
16521 cpr.provider = null;
16524 app.pubProviders.clear();
16526 // Take care of any launching providers waiting for this process.
16527 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16531 // Unregister from connected content providers.
16532 if (!app.conProviders.isEmpty()) {
16533 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16534 ContentProviderConnection conn = app.conProviders.get(i);
16535 conn.provider.connections.remove(conn);
16536 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16537 conn.provider.name);
16539 app.conProviders.clear();
16542 // At this point there may be remaining entries in mLaunchingProviders
16543 // where we were the only one waiting, so they are no longer of use.
16544 // Look for these and clean up if found.
16545 // XXX Commented out for now. Trying to figure out a way to reproduce
16546 // the actual situation to identify what is actually going on.
16548 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16549 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16550 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16551 synchronized (cpr) {
16552 cpr.launchingApp = null;
16559 skipCurrentReceiverLocked(app);
16561 // Unregister any receivers.
16562 for (int i = app.receivers.size() - 1; i >= 0; i--) {
16563 removeReceiverLocked(app.receivers.valueAt(i));
16565 app.receivers.clear();
16567 // If the app is undergoing backup, tell the backup manager about it
16568 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16569 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16570 + mBackupTarget.appInfo + " died during backup");
16572 IBackupManager bm = IBackupManager.Stub.asInterface(
16573 ServiceManager.getService(Context.BACKUP_SERVICE));
16574 bm.agentDisconnected(app.info.packageName);
16575 } catch (RemoteException e) {
16576 // can't happen; backup manager is local
16580 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16581 ProcessChangeItem item = mPendingProcessChanges.get(i);
16582 if (item.pid == app.pid) {
16583 mPendingProcessChanges.remove(i);
16584 mAvailProcessChanges.add(item);
16587 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16588 null).sendToTarget();
16590 // If the caller is restarting this app, then leave it in its
16591 // current lists and let the caller take care of it.
16596 if (!app.persistent || app.isolated) {
16597 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16598 "Removing non-persistent process during cleanup: " + app);
16599 removeProcessNameLocked(app.processName, app.uid);
16600 if (mHeavyWeightProcess == app) {
16601 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16602 mHeavyWeightProcess.userId, 0));
16603 mHeavyWeightProcess = null;
16605 } else if (!app.removed) {
16606 // This app is persistent, so we need to keep its record around.
16607 // If it is not already on the pending app list, add it there
16608 // and start a new process for it.
16609 if (mPersistentStartingProcesses.indexOf(app) < 0) {
16610 mPersistentStartingProcesses.add(app);
16614 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16615 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16616 mProcessesOnHold.remove(app);
16618 if (app == mHomeProcess) {
16619 mHomeProcess = null;
16621 if (app == mPreviousProcess) {
16622 mPreviousProcess = null;
16625 if (restart && !app.isolated) {
16626 // We have components that still need to be running in the
16627 // process, so re-launch it.
16629 ProcessList.remove(app.pid);
16631 addProcessNameLocked(app);
16632 startProcessLocked(app, "restart", app.processName);
16634 } else if (app.pid > 0 && app.pid != MY_PID) {
16637 synchronized (mPidsSelfLocked) {
16638 mPidsSelfLocked.remove(app.pid);
16639 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16641 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16642 if (app.isolated) {
16643 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16650 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16651 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16652 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16653 if (cpr.launchingApp == app) {
16660 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16661 // Look through the content providers we are waiting to have launched,
16662 // and if any run in this process then either schedule a restart of
16663 // the process or kill the client waiting for it if this process has
16665 boolean restart = false;
16666 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16667 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16668 if (cpr.launchingApp == app) {
16669 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16672 removeDyingProviderLocked(app, cpr, true);
16679 // =========================================================
16681 // =========================================================
16684 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16686 enforceNotIsolatedCaller("getServices");
16687 synchronized (this) {
16688 return mServices.getRunningServiceInfoLocked(maxNum, flags);
16693 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16694 enforceNotIsolatedCaller("getRunningServiceControlPanel");
16695 synchronized (this) {
16696 return mServices.getRunningServiceControlPanelLocked(name);
16701 public ComponentName startService(IApplicationThread caller, Intent service,
16702 String resolvedType, String callingPackage, int userId)
16703 throws TransactionTooLargeException {
16704 enforceNotIsolatedCaller("startService");
16705 // Refuse possible leaked file descriptors
16706 if (service != null && service.hasFileDescriptors() == true) {
16707 throw new IllegalArgumentException("File descriptors passed in Intent");
16710 if (callingPackage == null) {
16711 throw new IllegalArgumentException("callingPackage cannot be null");
16714 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16715 "startService: " + service + " type=" + resolvedType);
16716 synchronized(this) {
16717 final int callingPid = Binder.getCallingPid();
16718 final int callingUid = Binder.getCallingUid();
16719 final long origId = Binder.clearCallingIdentity();
16720 ComponentName res = mServices.startServiceLocked(caller, service,
16721 resolvedType, callingPid, callingUid, callingPackage, userId);
16722 Binder.restoreCallingIdentity(origId);
16727 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16728 String callingPackage, int userId)
16729 throws TransactionTooLargeException {
16730 synchronized(this) {
16731 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16732 "startServiceInPackage: " + service + " type=" + resolvedType);
16733 final long origId = Binder.clearCallingIdentity();
16734 ComponentName res = mServices.startServiceLocked(null, service,
16735 resolvedType, -1, uid, callingPackage, userId);
16736 Binder.restoreCallingIdentity(origId);
16742 public int stopService(IApplicationThread caller, Intent service,
16743 String resolvedType, int userId) {
16744 enforceNotIsolatedCaller("stopService");
16745 // Refuse possible leaked file descriptors
16746 if (service != null && service.hasFileDescriptors() == true) {
16747 throw new IllegalArgumentException("File descriptors passed in Intent");
16750 synchronized(this) {
16751 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16756 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16757 enforceNotIsolatedCaller("peekService");
16758 // Refuse possible leaked file descriptors
16759 if (service != null && service.hasFileDescriptors() == true) {
16760 throw new IllegalArgumentException("File descriptors passed in Intent");
16763 if (callingPackage == null) {
16764 throw new IllegalArgumentException("callingPackage cannot be null");
16767 synchronized(this) {
16768 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16773 public boolean stopServiceToken(ComponentName className, IBinder token,
16775 synchronized(this) {
16776 return mServices.stopServiceTokenLocked(className, token, startId);
16781 public void setServiceForeground(ComponentName className, IBinder token,
16782 int id, Notification notification, int flags) {
16783 synchronized(this) {
16784 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
16789 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16790 boolean requireFull, String name, String callerPackage) {
16791 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16792 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16795 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16796 String className, int flags) {
16797 boolean result = false;
16798 // For apps that don't have pre-defined UIDs, check for permission
16799 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16800 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16801 if (ActivityManager.checkUidPermission(
16802 INTERACT_ACROSS_USERS,
16803 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16804 ComponentName comp = new ComponentName(aInfo.packageName, className);
16805 String msg = "Permission Denial: Component " + comp.flattenToShortString()
16806 + " requests FLAG_SINGLE_USER, but app does not hold "
16807 + INTERACT_ACROSS_USERS;
16809 throw new SecurityException(msg);
16811 // Permission passed
16814 } else if ("system".equals(componentProcessName)) {
16816 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16817 // Phone app and persistent apps are allowed to export singleuser providers.
16818 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16819 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16821 if (DEBUG_MU) Slog.v(TAG_MU,
16822 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16823 + Integer.toHexString(flags) + ") = " + result);
16828 * Checks to see if the caller is in the same app as the singleton
16829 * component, or the component is in a special app. It allows special apps
16830 * to export singleton components but prevents exporting singleton
16831 * components for regular apps.
16833 boolean isValidSingletonCall(int callingUid, int componentUid) {
16834 int componentAppId = UserHandle.getAppId(componentUid);
16835 return UserHandle.isSameApp(callingUid, componentUid)
16836 || componentAppId == Process.SYSTEM_UID
16837 || componentAppId == Process.PHONE_UID
16838 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16839 == PackageManager.PERMISSION_GRANTED;
16842 public int bindService(IApplicationThread caller, IBinder token, Intent service,
16843 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16844 int userId) throws TransactionTooLargeException {
16845 enforceNotIsolatedCaller("bindService");
16847 // Refuse possible leaked file descriptors
16848 if (service != null && service.hasFileDescriptors() == true) {
16849 throw new IllegalArgumentException("File descriptors passed in Intent");
16852 if (callingPackage == null) {
16853 throw new IllegalArgumentException("callingPackage cannot be null");
16856 synchronized(this) {
16857 return mServices.bindServiceLocked(caller, token, service,
16858 resolvedType, connection, flags, callingPackage, userId);
16862 public boolean unbindService(IServiceConnection connection) {
16863 synchronized (this) {
16864 return mServices.unbindServiceLocked(connection);
16868 public void publishService(IBinder token, Intent intent, IBinder service) {
16869 // Refuse possible leaked file descriptors
16870 if (intent != null && intent.hasFileDescriptors() == true) {
16871 throw new IllegalArgumentException("File descriptors passed in Intent");
16874 synchronized(this) {
16875 if (!(token instanceof ServiceRecord)) {
16876 throw new IllegalArgumentException("Invalid service token");
16878 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16882 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16883 // Refuse possible leaked file descriptors
16884 if (intent != null && intent.hasFileDescriptors() == true) {
16885 throw new IllegalArgumentException("File descriptors passed in Intent");
16888 synchronized(this) {
16889 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16893 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16894 synchronized(this) {
16895 if (!(token instanceof ServiceRecord)) {
16896 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16897 throw new IllegalArgumentException("Invalid service token");
16899 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16903 // =========================================================
16904 // BACKUP AND RESTORE
16905 // =========================================================
16907 // Cause the target app to be launched if necessary and its backup agent
16908 // instantiated. The backup agent will invoke backupAgentCreated() on the
16909 // activity manager to announce its creation.
16910 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16911 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16912 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16913 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16915 synchronized(this) {
16916 // !!! TODO: currently no check here that we're already bound
16917 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16918 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16919 synchronized (stats) {
16920 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16923 // Backup agent is now in use, its package can't be stopped.
16925 AppGlobals.getPackageManager().setPackageStoppedState(
16926 app.packageName, false, UserHandle.getUserId(app.uid));
16927 } catch (RemoteException e) {
16928 } catch (IllegalArgumentException e) {
16929 Slog.w(TAG, "Failed trying to unstop package "
16930 + app.packageName + ": " + e);
16933 BackupRecord r = new BackupRecord(ss, app, backupMode);
16934 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16935 ? new ComponentName(app.packageName, app.backupAgentName)
16936 : new ComponentName("android", "FullBackupAgent");
16937 // startProcessLocked() returns existing proc's record if it's already running
16938 ProcessRecord proc = startProcessLocked(app.processName, app,
16939 false, 0, "backup", hostingName, false, false, false);
16940 if (proc == null) {
16941 Slog.e(TAG, "Unable to start backup agent process " + r);
16945 // If the app is a regular app (uid >= 10000) and not the system server or phone
16946 // process, etc, then mark it as being in full backup so that certain calls to the
16947 // process can be blocked. This is not reset to false anywhere because we kill the
16948 // process after the full backup is done and the ProcessRecord will vaporize anyway.
16949 if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
16950 proc.inFullBackup = true;
16954 mBackupAppName = app.packageName;
16956 // Try not to kill the process during backup
16957 updateOomAdjLocked(proc);
16959 // If the process is already attached, schedule the creation of the backup agent now.
16960 // If it is not yet live, this will be done when it attaches to the framework.
16961 if (proc.thread != null) {
16962 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16964 proc.thread.scheduleCreateBackupAgent(app,
16965 compatibilityInfoForPackageLocked(app), backupMode);
16966 } catch (RemoteException e) {
16967 // Will time out on the backup manager side
16970 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16972 // Invariants: at this point, the target app process exists and the application
16973 // is either already running or in the process of coming up. mBackupTarget and
16974 // mBackupAppName describe the app, so that when it binds back to the AM we
16975 // know that it's scheduled for a backup-agent operation.
16982 public void clearPendingBackup() {
16983 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16984 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16986 synchronized (this) {
16987 mBackupTarget = null;
16988 mBackupAppName = null;
16992 // A backup agent has just come up
16993 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16994 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16997 synchronized(this) {
16998 if (!agentPackageName.equals(mBackupAppName)) {
16999 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17004 long oldIdent = Binder.clearCallingIdentity();
17006 IBackupManager bm = IBackupManager.Stub.asInterface(
17007 ServiceManager.getService(Context.BACKUP_SERVICE));
17008 bm.agentConnected(agentPackageName, agent);
17009 } catch (RemoteException e) {
17010 // can't happen; the backup manager service is local
17011 } catch (Exception e) {
17012 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17013 e.printStackTrace();
17015 Binder.restoreCallingIdentity(oldIdent);
17019 // done with this agent
17020 public void unbindBackupAgent(ApplicationInfo appInfo) {
17021 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17022 if (appInfo == null) {
17023 Slog.w(TAG, "unbind backup agent for null app");
17027 synchronized(this) {
17029 if (mBackupAppName == null) {
17030 Slog.w(TAG, "Unbinding backup agent with no active backup");
17034 if (!mBackupAppName.equals(appInfo.packageName)) {
17035 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17039 // Not backing this app up any more; reset its OOM adjustment
17040 final ProcessRecord proc = mBackupTarget.app;
17041 updateOomAdjLocked(proc);
17043 // If the app crashed during backup, 'thread' will be null here
17044 if (proc.thread != null) {
17046 proc.thread.scheduleDestroyBackupAgent(appInfo,
17047 compatibilityInfoForPackageLocked(appInfo));
17048 } catch (Exception e) {
17049 Slog.e(TAG, "Exception when unbinding backup agent:");
17050 e.printStackTrace();
17054 mBackupTarget = null;
17055 mBackupAppName = null;
17059 // =========================================================
17061 // =========================================================
17063 boolean isPendingBroadcastProcessLocked(int pid) {
17064 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17065 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17068 void skipPendingBroadcastLocked(int pid) {
17069 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17070 for (BroadcastQueue queue : mBroadcastQueues) {
17071 queue.skipPendingBroadcastLocked(pid);
17075 // The app just attached; send any pending broadcasts that it should receive
17076 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17077 boolean didSomething = false;
17078 for (BroadcastQueue queue : mBroadcastQueues) {
17079 didSomething |= queue.sendPendingBroadcastsLocked(app);
17081 return didSomething;
17084 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17085 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17086 enforceNotIsolatedCaller("registerReceiver");
17087 ArrayList<Intent> stickyIntents = null;
17088 ProcessRecord callerApp = null;
17091 synchronized(this) {
17092 if (caller != null) {
17093 callerApp = getRecordForAppLocked(caller);
17094 if (callerApp == null) {
17095 throw new SecurityException(
17096 "Unable to find app for caller " + caller
17097 + " (pid=" + Binder.getCallingPid()
17098 + ") when registering receiver " + receiver);
17100 if (callerApp.info.uid != Process.SYSTEM_UID &&
17101 !callerApp.pkgList.containsKey(callerPackage) &&
17102 !"android".equals(callerPackage)) {
17103 throw new SecurityException("Given caller package " + callerPackage
17104 + " is not running in process " + callerApp);
17106 callingUid = callerApp.info.uid;
17107 callingPid = callerApp.pid;
17109 callerPackage = null;
17110 callingUid = Binder.getCallingUid();
17111 callingPid = Binder.getCallingPid();
17114 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17115 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17117 Iterator<String> actions = filter.actionsIterator();
17118 if (actions == null) {
17119 ArrayList<String> noAction = new ArrayList<String>(1);
17120 noAction.add(null);
17121 actions = noAction.iterator();
17124 // Collect stickies of users
17125 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17126 while (actions.hasNext()) {
17127 String action = actions.next();
17128 for (int id : userIds) {
17129 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17130 if (stickies != null) {
17131 ArrayList<Intent> intents = stickies.get(action);
17132 if (intents != null) {
17133 if (stickyIntents == null) {
17134 stickyIntents = new ArrayList<Intent>();
17136 stickyIntents.addAll(intents);
17143 ArrayList<Intent> allSticky = null;
17144 if (stickyIntents != null) {
17145 final ContentResolver resolver = mContext.getContentResolver();
17146 // Look for any matching sticky broadcasts...
17147 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17148 Intent intent = stickyIntents.get(i);
17149 // If intent has scheme "content", it will need to acccess
17150 // provider that needs to lock mProviderMap in ActivityThread
17151 // and also it may need to wait application response, so we
17152 // cannot lock ActivityManagerService here.
17153 if (filter.match(resolver, intent, true, TAG) >= 0) {
17154 if (allSticky == null) {
17155 allSticky = new ArrayList<Intent>();
17157 allSticky.add(intent);
17162 // The first sticky in the list is returned directly back to the client.
17163 Intent sticky = allSticky != null ? allSticky.get(0) : null;
17164 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17165 if (receiver == null) {
17169 synchronized (this) {
17170 if (callerApp != null && (callerApp.thread == null
17171 || callerApp.thread.asBinder() != caller.asBinder())) {
17172 // Original caller already died
17175 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17177 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17179 if (rl.app != null) {
17180 rl.app.receivers.add(rl);
17183 receiver.asBinder().linkToDeath(rl, 0);
17184 } catch (RemoteException e) {
17187 rl.linkedToDeath = true;
17189 mRegisteredReceivers.put(receiver.asBinder(), rl);
17190 } else if (rl.uid != callingUid) {
17191 throw new IllegalArgumentException(
17192 "Receiver requested to register for uid " + callingUid
17193 + " was previously registered for uid " + rl.uid);
17194 } else if (rl.pid != callingPid) {
17195 throw new IllegalArgumentException(
17196 "Receiver requested to register for pid " + callingPid
17197 + " was previously registered for pid " + rl.pid);
17198 } else if (rl.userId != userId) {
17199 throw new IllegalArgumentException(
17200 "Receiver requested to register for user " + userId
17201 + " was previously registered for user " + rl.userId);
17203 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17204 permission, callingUid, userId);
17206 if (!bf.debugCheck()) {
17207 Slog.w(TAG, "==> For Dynamic broadcast");
17209 mReceiverResolver.addFilter(bf);
17211 // Enqueue broadcasts for all existing stickies that match
17213 if (allSticky != null) {
17214 ArrayList receivers = new ArrayList();
17217 final int stickyCount = allSticky.size();
17218 for (int i = 0; i < stickyCount; i++) {
17219 Intent intent = allSticky.get(i);
17220 BroadcastQueue queue = broadcastQueueForIntent(intent);
17221 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17222 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17223 null, 0, null, null, false, true, true, -1);
17224 queue.enqueueParallelBroadcastLocked(r);
17225 queue.scheduleBroadcastsLocked();
17233 public void unregisterReceiver(IIntentReceiver receiver) {
17234 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17236 final long origId = Binder.clearCallingIdentity();
17238 boolean doTrim = false;
17240 synchronized(this) {
17241 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17243 final BroadcastRecord r = rl.curBroadcast;
17244 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17245 final boolean doNext = r.queue.finishReceiverLocked(
17246 r, r.resultCode, r.resultData, r.resultExtras,
17247 r.resultAbort, false);
17250 r.queue.processNextBroadcast(false);
17254 if (rl.app != null) {
17255 rl.app.receivers.remove(rl);
17257 removeReceiverLocked(rl);
17258 if (rl.linkedToDeath) {
17259 rl.linkedToDeath = false;
17260 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17265 // If we actually concluded any broadcasts, we might now be able
17266 // to trim the recipients' apps from our working set
17268 trimApplications();
17273 Binder.restoreCallingIdentity(origId);
17277 void removeReceiverLocked(ReceiverList rl) {
17278 mRegisteredReceivers.remove(rl.receiver.asBinder());
17279 for (int i = rl.size() - 1; i >= 0; i--) {
17280 mReceiverResolver.removeFilter(rl.get(i));
17284 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17285 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17286 ProcessRecord r = mLruProcesses.get(i);
17287 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17289 r.thread.dispatchPackageBroadcast(cmd, packages);
17290 } catch (RemoteException ex) {
17296 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17297 int callingUid, int[] users) {
17298 // TODO: come back and remove this assumption to triage all broadcasts
17299 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17301 List<ResolveInfo> receivers = null;
17303 HashSet<ComponentName> singleUserReceivers = null;
17304 boolean scannedFirstReceivers = false;
17305 for (int user : users) {
17306 // Skip users that have Shell restrictions, with exception of always permitted
17307 // Shell broadcasts
17308 if (callingUid == Process.SHELL_UID
17309 && mUserController.hasUserRestriction(
17310 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17311 && !isPermittedShellBroadcast(intent)) {
17314 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17315 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17316 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17317 // If this is not the system user, we need to check for
17318 // any receivers that should be filtered out.
17319 for (int i=0; i<newReceivers.size(); i++) {
17320 ResolveInfo ri = newReceivers.get(i);
17321 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17322 newReceivers.remove(i);
17327 if (newReceivers != null && newReceivers.size() == 0) {
17328 newReceivers = null;
17330 if (receivers == null) {
17331 receivers = newReceivers;
17332 } else if (newReceivers != null) {
17333 // We need to concatenate the additional receivers
17334 // found with what we have do far. This would be easy,
17335 // but we also need to de-dup any receivers that are
17337 if (!scannedFirstReceivers) {
17338 // Collect any single user receivers we had already retrieved.
17339 scannedFirstReceivers = true;
17340 for (int i=0; i<receivers.size(); i++) {
17341 ResolveInfo ri = receivers.get(i);
17342 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17343 ComponentName cn = new ComponentName(
17344 ri.activityInfo.packageName, ri.activityInfo.name);
17345 if (singleUserReceivers == null) {
17346 singleUserReceivers = new HashSet<ComponentName>();
17348 singleUserReceivers.add(cn);
17352 // Add the new results to the existing results, tracking
17353 // and de-dupping single user receivers.
17354 for (int i=0; i<newReceivers.size(); i++) {
17355 ResolveInfo ri = newReceivers.get(i);
17356 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17357 ComponentName cn = new ComponentName(
17358 ri.activityInfo.packageName, ri.activityInfo.name);
17359 if (singleUserReceivers == null) {
17360 singleUserReceivers = new HashSet<ComponentName>();
17362 if (!singleUserReceivers.contains(cn)) {
17363 singleUserReceivers.add(cn);
17372 } catch (RemoteException ex) {
17373 // pm is in same process, this will never happen.
17378 private boolean isPermittedShellBroadcast(Intent intent) {
17379 // remote bugreport should always be allowed to be taken
17380 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17383 final int broadcastIntentLocked(ProcessRecord callerApp,
17384 String callerPackage, Intent intent, String resolvedType,
17385 IIntentReceiver resultTo, int resultCode, String resultData,
17386 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17387 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17388 intent = new Intent(intent);
17390 // By default broadcasts do not go to stopped apps.
17391 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17393 // If we have not finished booting, don't allow this to launch new processes.
17394 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17395 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17398 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17399 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17400 + " ordered=" + ordered + " userid=" + userId);
17401 if ((resultTo != null) && !ordered) {
17402 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17405 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17406 ALLOW_NON_FULL, "broadcast", callerPackage);
17408 // Make sure that the user who is receiving this broadcast is running.
17409 // If not, we will just skip it. Make an exception for shutdown broadcasts
17410 // and upgrade steps.
17412 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17413 if ((callingUid != Process.SYSTEM_UID
17414 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17415 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17416 Slog.w(TAG, "Skipping broadcast of " + intent
17417 + ": user " + userId + " is stopped");
17418 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17422 BroadcastOptions brOptions = null;
17423 if (bOptions != null) {
17424 brOptions = new BroadcastOptions(bOptions);
17425 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17426 // See if the caller is allowed to do this. Note we are checking against
17427 // the actual real caller (not whoever provided the operation as say a
17428 // PendingIntent), because that who is actually supplied the arguments.
17429 if (checkComponentPermission(
17430 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17431 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17432 != PackageManager.PERMISSION_GRANTED) {
17433 String msg = "Permission Denial: " + intent.getAction()
17434 + " broadcast from " + callerPackage + " (pid=" + callingPid
17435 + ", uid=" + callingUid + ")"
17437 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17439 throw new SecurityException(msg);
17444 // Verify that protected broadcasts are only being sent by system code,
17445 // and that system code is only sending protected broadcasts.
17446 final String action = intent.getAction();
17447 final boolean isProtectedBroadcast;
17449 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17450 } catch (RemoteException e) {
17451 Slog.w(TAG, "Remote exception", e);
17452 return ActivityManager.BROADCAST_SUCCESS;
17455 final boolean isCallerSystem;
17456 switch (UserHandle.getAppId(callingUid)) {
17457 case Process.ROOT_UID:
17458 case Process.SYSTEM_UID:
17459 case Process.PHONE_UID:
17460 case Process.BLUETOOTH_UID:
17461 case Process.NFC_UID:
17462 isCallerSystem = true;
17465 isCallerSystem = (callerApp != null) && callerApp.persistent;
17469 if (isCallerSystem) {
17470 if (isProtectedBroadcast
17471 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17472 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17473 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17474 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17475 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17476 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17477 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17478 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17479 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17480 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17481 // Broadcast is either protected, or it's a public action that
17482 // we've relaxed, so it's fine for system internals to send.
17484 // The vast majority of broadcasts sent from system internals
17485 // should be protected to avoid security holes, so yell loudly
17486 // to ensure we examine these cases.
17487 if (callerApp != null) {
17488 Log.wtf(TAG, "Sending non-protected broadcast " + action
17489 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17492 Log.wtf(TAG, "Sending non-protected broadcast " + action
17493 + " from system uid " + UserHandle.formatUid(callingUid)
17494 + " pkg " + callerPackage,
17500 if (isProtectedBroadcast) {
17501 String msg = "Permission Denial: not allowed to send broadcast "
17502 + action + " from pid="
17503 + callingPid + ", uid=" + callingUid;
17505 throw new SecurityException(msg);
17507 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17508 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17509 // Special case for compatibility: we don't want apps to send this,
17510 // but historically it has not been protected and apps may be using it
17511 // to poke their own app widget. So, instead of making it protected,
17512 // just limit it to the caller.
17513 if (callerPackage == null) {
17514 String msg = "Permission Denial: not allowed to send broadcast "
17515 + action + " from unknown caller.";
17517 throw new SecurityException(msg);
17518 } else if (intent.getComponent() != null) {
17519 // They are good enough to send to an explicit component... verify
17520 // it is being sent to the calling app.
17521 if (!intent.getComponent().getPackageName().equals(
17523 String msg = "Permission Denial: not allowed to send broadcast "
17525 + intent.getComponent().getPackageName() + " from "
17528 throw new SecurityException(msg);
17531 // Limit broadcast to their own package.
17532 intent.setPackage(callerPackage);
17537 if (action != null) {
17539 case Intent.ACTION_UID_REMOVED:
17540 case Intent.ACTION_PACKAGE_REMOVED:
17541 case Intent.ACTION_PACKAGE_CHANGED:
17542 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17543 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17544 case Intent.ACTION_PACKAGES_SUSPENDED:
17545 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17546 // Handle special intents: if this broadcast is from the package
17547 // manager about a package being removed, we need to remove all of
17548 // its activities from the history stack.
17549 if (checkComponentPermission(
17550 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17551 callingPid, callingUid, -1, true)
17552 != PackageManager.PERMISSION_GRANTED) {
17553 String msg = "Permission Denial: " + intent.getAction()
17554 + " broadcast from " + callerPackage + " (pid=" + callingPid
17555 + ", uid=" + callingUid + ")"
17557 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17559 throw new SecurityException(msg);
17562 case Intent.ACTION_UID_REMOVED:
17563 final Bundle intentExtras = intent.getExtras();
17564 final int uid = intentExtras != null
17565 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17567 mBatteryStatsService.removeUid(uid);
17568 mAppOpsService.uidRemoved(uid);
17571 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17572 // If resources are unavailable just force stop all those packages
17573 // and flush the attribute cache as well.
17575 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17576 if (list != null && list.length > 0) {
17577 for (int i = 0; i < list.length; i++) {
17578 forceStopPackageLocked(list[i], -1, false, true, true,
17579 false, false, userId, "storage unmount");
17581 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17582 sendPackageBroadcastLocked(
17583 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17587 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17588 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17590 case Intent.ACTION_PACKAGE_REMOVED:
17591 case Intent.ACTION_PACKAGE_CHANGED:
17592 Uri data = intent.getData();
17594 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17595 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17596 final boolean replacing =
17597 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17598 final boolean killProcess =
17599 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17600 final boolean fullUninstall = removed && !replacing;
17603 forceStopPackageLocked(ssp, UserHandle.getAppId(
17604 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17605 false, true, true, false, fullUninstall, userId,
17606 removed ? "pkg removed" : "pkg changed");
17608 final int cmd = killProcess
17609 ? IApplicationThread.PACKAGE_REMOVED
17610 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17611 sendPackageBroadcastLocked(cmd,
17612 new String[] {ssp}, userId);
17613 if (fullUninstall) {
17614 mAppOpsService.packageRemoved(
17615 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17617 // Remove all permissions granted from/to this package
17618 removeUriPermissionsForPackageLocked(ssp, userId, true);
17620 removeTasksByPackageNameLocked(ssp, userId);
17621 mBatteryStatsService.notePackageUninstalled(ssp);
17625 killPackageProcessesLocked(ssp, UserHandle.getAppId(
17626 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17627 userId, ProcessList.INVALID_ADJ,
17628 false, true, true, false, "change " + ssp);
17630 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17631 intent.getStringArrayExtra(
17632 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17636 case Intent.ACTION_PACKAGES_SUSPENDED:
17637 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17638 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17639 intent.getAction());
17640 final String[] packageNames = intent.getStringArrayExtra(
17641 Intent.EXTRA_CHANGED_PACKAGE_LIST);
17642 final int userHandle = intent.getIntExtra(
17643 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17645 synchronized(ActivityManagerService.this) {
17646 mRecentTasks.onPackagesSuspendedChanged(
17647 packageNames, suspended, userHandle);
17652 case Intent.ACTION_PACKAGE_REPLACED:
17654 final Uri data = intent.getData();
17656 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17657 final ApplicationInfo aInfo =
17658 getPackageManagerInternalLocked().getApplicationInfo(
17661 if (aInfo == null) {
17662 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
17663 + " ssp=" + ssp + " data=" + data);
17664 return ActivityManager.BROADCAST_SUCCESS;
17666 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17667 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17668 new String[] {ssp}, userId);
17672 case Intent.ACTION_PACKAGE_ADDED:
17674 // Special case for adding a package: by default turn on compatibility mode.
17675 Uri data = intent.getData();
17677 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17678 final boolean replacing =
17679 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17680 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17683 ApplicationInfo ai = AppGlobals.getPackageManager().
17684 getApplicationInfo(ssp, 0, 0);
17685 mBatteryStatsService.notePackageInstalled(ssp,
17686 ai != null ? ai.versionCode : 0);
17687 } catch (RemoteException e) {
17692 case Intent.ACTION_TIMEZONE_CHANGED:
17693 // If this is the time zone changed action, queue up a message that will reset
17694 // the timezone of all currently running processes. This message will get
17695 // queued up before the broadcast happens.
17696 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17698 case Intent.ACTION_TIME_CHANGED:
17699 // If the user set the time, let all running processes know.
17700 final int is24Hour =
17701 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17703 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17704 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17705 synchronized (stats) {
17706 stats.noteCurrentTimeChangedLocked();
17709 case Intent.ACTION_CLEAR_DNS_CACHE:
17710 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17712 case Proxy.PROXY_CHANGE_ACTION:
17713 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17714 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17716 case android.hardware.Camera.ACTION_NEW_PICTURE:
17717 case android.hardware.Camera.ACTION_NEW_VIDEO:
17718 // These broadcasts are no longer allowed by the system, since they can
17719 // cause significant thrashing at a crictical point (using the camera).
17720 // Apps should use JobScehduler to monitor for media provider changes.
17721 Slog.w(TAG, action + " no longer allowed; dropping from "
17722 + UserHandle.formatUid(callingUid));
17723 // Lie; we don't want to crash the app.
17724 return ActivityManager.BROADCAST_SUCCESS;
17728 // Add to the sticky list if requested.
17730 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17731 callingPid, callingUid)
17732 != PackageManager.PERMISSION_GRANTED) {
17733 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17734 + callingPid + ", uid=" + callingUid
17735 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17737 throw new SecurityException(msg);
17739 if (requiredPermissions != null && requiredPermissions.length > 0) {
17740 Slog.w(TAG, "Can't broadcast sticky intent " + intent
17741 + " and enforce permissions " + Arrays.toString(requiredPermissions));
17742 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17744 if (intent.getComponent() != null) {
17745 throw new SecurityException(
17746 "Sticky broadcasts can't target a specific component");
17748 // We use userId directly here, since the "all" target is maintained
17749 // as a separate set of sticky broadcasts.
17750 if (userId != UserHandle.USER_ALL) {
17751 // But first, if this is not a broadcast to all users, then
17752 // make sure it doesn't conflict with an existing broadcast to
17754 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17755 UserHandle.USER_ALL);
17756 if (stickies != null) {
17757 ArrayList<Intent> list = stickies.get(intent.getAction());
17758 if (list != null) {
17759 int N = list.size();
17761 for (i=0; i<N; i++) {
17762 if (intent.filterEquals(list.get(i))) {
17763 throw new IllegalArgumentException(
17764 "Sticky broadcast " + intent + " for user "
17765 + userId + " conflicts with existing global broadcast");
17771 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17772 if (stickies == null) {
17773 stickies = new ArrayMap<>();
17774 mStickyBroadcasts.put(userId, stickies);
17776 ArrayList<Intent> list = stickies.get(intent.getAction());
17777 if (list == null) {
17778 list = new ArrayList<>();
17779 stickies.put(intent.getAction(), list);
17781 final int stickiesCount = list.size();
17783 for (i = 0; i < stickiesCount; i++) {
17784 if (intent.filterEquals(list.get(i))) {
17785 // This sticky already exists, replace it.
17786 list.set(i, new Intent(intent));
17790 if (i >= stickiesCount) {
17791 list.add(new Intent(intent));
17796 if (userId == UserHandle.USER_ALL) {
17797 // Caller wants broadcast to go to all started users.
17798 users = mUserController.getStartedUserArrayLocked();
17800 // Caller wants broadcast to go to one specific user.
17801 users = new int[] {userId};
17804 // Figure out who all will receive this broadcast.
17805 List receivers = null;
17806 List<BroadcastFilter> registeredReceivers = null;
17807 // Need to resolve the intent to interested receivers...
17808 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17810 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17812 if (intent.getComponent() == null) {
17813 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17814 // Query one target user at a time, excluding shell-restricted users
17815 for (int i = 0; i < users.length; i++) {
17816 if (mUserController.hasUserRestriction(
17817 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17820 List<BroadcastFilter> registeredReceiversForUser =
17821 mReceiverResolver.queryIntent(intent,
17822 resolvedType, false, users[i]);
17823 if (registeredReceivers == null) {
17824 registeredReceivers = registeredReceiversForUser;
17825 } else if (registeredReceiversForUser != null) {
17826 registeredReceivers.addAll(registeredReceiversForUser);
17830 registeredReceivers = mReceiverResolver.queryIntent(intent,
17831 resolvedType, false, userId);
17835 final boolean replacePending =
17836 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17838 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17839 + " replacePending=" + replacePending);
17841 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17842 if (!ordered && NR > 0) {
17843 // If we are not serializing this broadcast, then send the
17844 // registered receivers separately so they don't wait for the
17845 // components to be launched.
17846 final BroadcastQueue queue = broadcastQueueForIntent(intent);
17847 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17848 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17849 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17850 resultExtras, ordered, sticky, false, userId);
17851 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17852 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17854 queue.enqueueParallelBroadcastLocked(r);
17855 queue.scheduleBroadcastsLocked();
17857 registeredReceivers = null;
17861 // Merge into one list.
17863 if (receivers != null) {
17864 // A special case for PACKAGE_ADDED: do not allow the package
17865 // being added to see this broadcast. This prevents them from
17866 // using this as a back door to get run as soon as they are
17867 // installed. Maybe in the future we want to have a special install
17868 // broadcast or such for apps, but we'd like to deliberately make
17870 String skipPackages[] = null;
17871 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17872 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17873 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17874 Uri data = intent.getData();
17875 if (data != null) {
17876 String pkgName = data.getSchemeSpecificPart();
17877 if (pkgName != null) {
17878 skipPackages = new String[] { pkgName };
17881 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17882 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17884 if (skipPackages != null && (skipPackages.length > 0)) {
17885 for (String skipPackage : skipPackages) {
17886 if (skipPackage != null) {
17887 int NT = receivers.size();
17888 for (int it=0; it<NT; it++) {
17889 ResolveInfo curt = (ResolveInfo)receivers.get(it);
17890 if (curt.activityInfo.packageName.equals(skipPackage)) {
17891 receivers.remove(it);
17900 int NT = receivers != null ? receivers.size() : 0;
17902 ResolveInfo curt = null;
17903 BroadcastFilter curr = null;
17904 while (it < NT && ir < NR) {
17905 if (curt == null) {
17906 curt = (ResolveInfo)receivers.get(it);
17908 if (curr == null) {
17909 curr = registeredReceivers.get(ir);
17911 if (curr.getPriority() >= curt.priority) {
17912 // Insert this broadcast record into the final list.
17913 receivers.add(it, curr);
17919 // Skip to the next ResolveInfo in the final list.
17926 if (receivers == null) {
17927 receivers = new ArrayList();
17929 receivers.add(registeredReceivers.get(ir));
17933 if ((receivers != null && receivers.size() > 0)
17934 || resultTo != null) {
17935 BroadcastQueue queue = broadcastQueueForIntent(intent);
17936 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17937 callerPackage, callingPid, callingUid, resolvedType,
17938 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17939 resultData, resultExtras, ordered, sticky, false, userId);
17941 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17942 + ": prev had " + queue.mOrderedBroadcasts.size());
17943 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17944 "Enqueueing broadcast " + r.intent.getAction());
17946 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17948 queue.enqueueOrderedBroadcastLocked(r);
17949 queue.scheduleBroadcastsLocked();
17953 return ActivityManager.BROADCAST_SUCCESS;
17956 final Intent verifyBroadcastLocked(Intent intent) {
17957 // Refuse possible leaked file descriptors
17958 if (intent != null && intent.hasFileDescriptors() == true) {
17959 throw new IllegalArgumentException("File descriptors passed in Intent");
17962 int flags = intent.getFlags();
17964 if (!mProcessesReady) {
17965 // if the caller really truly claims to know what they're doing, go
17966 // ahead and allow the broadcast without launching any receivers
17967 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17968 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17969 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17970 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17971 + " before boot completion");
17972 throw new IllegalStateException("Cannot broadcast before boot completed");
17976 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17977 throw new IllegalArgumentException(
17978 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17984 public final int broadcastIntent(IApplicationThread caller,
17985 Intent intent, String resolvedType, IIntentReceiver resultTo,
17986 int resultCode, String resultData, Bundle resultExtras,
17987 String[] requiredPermissions, int appOp, Bundle bOptions,
17988 boolean serialized, boolean sticky, int userId) {
17989 enforceNotIsolatedCaller("broadcastIntent");
17990 synchronized(this) {
17991 intent = verifyBroadcastLocked(intent);
17993 final ProcessRecord callerApp = getRecordForAppLocked(caller);
17994 final int callingPid = Binder.getCallingPid();
17995 final int callingUid = Binder.getCallingUid();
17996 final long origId = Binder.clearCallingIdentity();
17997 int res = broadcastIntentLocked(callerApp,
17998 callerApp != null ? callerApp.info.packageName : null,
17999 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18000 requiredPermissions, appOp, bOptions, serialized, sticky,
18001 callingPid, callingUid, userId);
18002 Binder.restoreCallingIdentity(origId);
18008 int broadcastIntentInPackage(String packageName, int uid,
18009 Intent intent, String resolvedType, IIntentReceiver resultTo,
18010 int resultCode, String resultData, Bundle resultExtras,
18011 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18013 synchronized(this) {
18014 intent = verifyBroadcastLocked(intent);
18016 final long origId = Binder.clearCallingIdentity();
18017 String[] requiredPermissions = requiredPermission == null ? null
18018 : new String[] {requiredPermission};
18019 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18020 resultTo, resultCode, resultData, resultExtras,
18021 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18022 sticky, -1, uid, userId);
18023 Binder.restoreCallingIdentity(origId);
18028 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18029 // Refuse possible leaked file descriptors
18030 if (intent != null && intent.hasFileDescriptors() == true) {
18031 throw new IllegalArgumentException("File descriptors passed in Intent");
18034 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18035 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18037 synchronized(this) {
18038 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18039 != PackageManager.PERMISSION_GRANTED) {
18040 String msg = "Permission Denial: unbroadcastIntent() from pid="
18041 + Binder.getCallingPid()
18042 + ", uid=" + Binder.getCallingUid()
18043 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18045 throw new SecurityException(msg);
18047 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18048 if (stickies != null) {
18049 ArrayList<Intent> list = stickies.get(intent.getAction());
18050 if (list != null) {
18051 int N = list.size();
18053 for (i=0; i<N; i++) {
18054 if (intent.filterEquals(list.get(i))) {
18059 if (list.size() <= 0) {
18060 stickies.remove(intent.getAction());
18063 if (stickies.size() <= 0) {
18064 mStickyBroadcasts.remove(userId);
18070 void backgroundServicesFinishedLocked(int userId) {
18071 for (BroadcastQueue queue : mBroadcastQueues) {
18072 queue.backgroundServicesFinishedLocked(userId);
18076 public void finishReceiver(IBinder who, int resultCode, String resultData,
18077 Bundle resultExtras, boolean resultAbort, int flags) {
18078 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18080 // Refuse possible leaked file descriptors
18081 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18082 throw new IllegalArgumentException("File descriptors passed in Bundle");
18085 final long origId = Binder.clearCallingIdentity();
18087 boolean doNext = false;
18090 synchronized(this) {
18091 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18092 ? mFgBroadcastQueue : mBgBroadcastQueue;
18093 r = queue.getMatchingOrderedReceiver(who);
18095 doNext = r.queue.finishReceiverLocked(r, resultCode,
18096 resultData, resultExtras, resultAbort, true);
18101 r.queue.processNextBroadcast(false);
18103 trimApplications();
18105 Binder.restoreCallingIdentity(origId);
18109 // =========================================================
18111 // =========================================================
18113 public boolean startInstrumentation(ComponentName className,
18114 String profileFile, int flags, Bundle arguments,
18115 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18116 int userId, String abiOverride) {
18117 enforceNotIsolatedCaller("startInstrumentation");
18118 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18119 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18120 // Refuse possible leaked file descriptors
18121 if (arguments != null && arguments.hasFileDescriptors()) {
18122 throw new IllegalArgumentException("File descriptors passed in Bundle");
18125 synchronized(this) {
18126 InstrumentationInfo ii = null;
18127 ApplicationInfo ai = null;
18129 ii = mContext.getPackageManager().getInstrumentationInfo(
18130 className, STOCK_PM_FLAGS);
18131 ai = AppGlobals.getPackageManager().getApplicationInfo(
18132 ii.targetPackage, STOCK_PM_FLAGS, userId);
18133 } catch (PackageManager.NameNotFoundException e) {
18134 } catch (RemoteException e) {
18137 reportStartInstrumentationFailureLocked(watcher, className,
18138 "Unable to find instrumentation info for: " + className);
18142 reportStartInstrumentationFailureLocked(watcher, className,
18143 "Unable to find instrumentation target package: " + ii.targetPackage);
18146 if (!ai.hasCode()) {
18147 reportStartInstrumentationFailureLocked(watcher, className,
18148 "Instrumentation target has no code: " + ii.targetPackage);
18152 int match = mContext.getPackageManager().checkSignatures(
18153 ii.targetPackage, ii.packageName);
18154 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18155 String msg = "Permission Denial: starting instrumentation "
18156 + className + " from pid="
18157 + Binder.getCallingPid()
18158 + ", uid=" + Binder.getCallingPid()
18159 + " not allowed because package " + ii.packageName
18160 + " does not have a signature matching the target "
18161 + ii.targetPackage;
18162 reportStartInstrumentationFailureLocked(watcher, className, msg);
18163 throw new SecurityException(msg);
18166 final long origId = Binder.clearCallingIdentity();
18167 // Instrumentation can kill and relaunch even persistent processes
18168 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18170 ProcessRecord app = addAppLocked(ai, false, abiOverride);
18171 app.instrumentationClass = className;
18172 app.instrumentationInfo = ai;
18173 app.instrumentationProfileFile = profileFile;
18174 app.instrumentationArguments = arguments;
18175 app.instrumentationWatcher = watcher;
18176 app.instrumentationUiAutomationConnection = uiAutomationConnection;
18177 app.instrumentationResultClass = className;
18178 Binder.restoreCallingIdentity(origId);
18185 * Report errors that occur while attempting to start Instrumentation. Always writes the
18186 * error to the logs, but if somebody is watching, send the report there too. This enables
18187 * the "am" command to report errors with more information.
18189 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
18190 * @param cn The component name of the instrumentation.
18191 * @param report The error report.
18193 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18194 ComponentName cn, String report) {
18195 Slog.w(TAG, report);
18196 if (watcher != null) {
18197 Bundle results = new Bundle();
18198 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18199 results.putString("Error", report);
18200 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18204 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18205 if (app.instrumentationWatcher != null) {
18206 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18207 app.instrumentationClass, resultCode, results);
18210 // Can't call out of the system process with a lock held, so post a message.
18211 if (app.instrumentationUiAutomationConnection != null) {
18212 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18213 app.instrumentationUiAutomationConnection).sendToTarget();
18216 app.instrumentationWatcher = null;
18217 app.instrumentationUiAutomationConnection = null;
18218 app.instrumentationClass = null;
18219 app.instrumentationInfo = null;
18220 app.instrumentationProfileFile = null;
18221 app.instrumentationArguments = null;
18223 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18227 public void finishInstrumentation(IApplicationThread target,
18228 int resultCode, Bundle results) {
18229 int userId = UserHandle.getCallingUserId();
18230 // Refuse possible leaked file descriptors
18231 if (results != null && results.hasFileDescriptors()) {
18232 throw new IllegalArgumentException("File descriptors passed in Intent");
18235 synchronized(this) {
18236 ProcessRecord app = getRecordForAppLocked(target);
18238 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18241 final long origId = Binder.clearCallingIdentity();
18242 finishInstrumentationLocked(app, resultCode, results);
18243 Binder.restoreCallingIdentity(origId);
18247 // =========================================================
18249 // =========================================================
18251 public ConfigurationInfo getDeviceConfigurationInfo() {
18252 ConfigurationInfo config = new ConfigurationInfo();
18253 synchronized (this) {
18254 config.reqTouchScreen = mConfiguration.touchscreen;
18255 config.reqKeyboardType = mConfiguration.keyboard;
18256 config.reqNavigation = mConfiguration.navigation;
18257 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18258 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18259 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18261 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18262 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18263 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18265 config.reqGlEsVersion = GL_ES_VERSION;
18270 ActivityStack getFocusedStack() {
18271 return mStackSupervisor.getFocusedStack();
18275 public int getFocusedStackId() throws RemoteException {
18276 ActivityStack focusedStack = getFocusedStack();
18277 if (focusedStack != null) {
18278 return focusedStack.getStackId();
18283 public Configuration getConfiguration() {
18285 synchronized(this) {
18286 ci = new Configuration(mConfiguration);
18287 ci.userSetLocale = false;
18293 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18294 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18295 synchronized (this) {
18296 mSuppressResizeConfigChanges = suppress;
18301 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18302 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18303 if (fromStackId == HOME_STACK_ID) {
18304 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18306 synchronized (this) {
18307 final long origId = Binder.clearCallingIdentity();
18309 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18311 Binder.restoreCallingIdentity(origId);
18317 public void updatePersistentConfiguration(Configuration values) {
18318 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18319 "updateConfiguration()");
18320 enforceWriteSettingsPermission("updateConfiguration()");
18321 if (values == null) {
18322 throw new NullPointerException("Configuration must not be null");
18325 int userId = UserHandle.getCallingUserId();
18327 synchronized(this) {
18328 final long origId = Binder.clearCallingIdentity();
18329 updateConfigurationLocked(values, null, false, true, userId);
18330 Binder.restoreCallingIdentity(origId);
18334 private void updateFontScaleIfNeeded() {
18335 final int currentUserId;
18336 synchronized(this) {
18337 currentUserId = mUserController.getCurrentUserIdLocked();
18339 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18340 FONT_SCALE, 1.0f, currentUserId);
18341 if (mConfiguration.fontScale != scaleFactor) {
18342 final Configuration configuration = mWindowManager.computeNewConfiguration();
18343 configuration.fontScale = scaleFactor;
18344 updatePersistentConfiguration(configuration);
18348 private void enforceWriteSettingsPermission(String func) {
18349 int uid = Binder.getCallingUid();
18350 if (uid == Process.ROOT_UID) {
18354 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18355 Settings.getPackageNameForUid(mContext, uid), false)) {
18359 String msg = "Permission Denial: " + func + " from pid="
18360 + Binder.getCallingPid()
18362 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18364 throw new SecurityException(msg);
18367 public void updateConfiguration(Configuration values) {
18368 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18369 "updateConfiguration()");
18371 synchronized(this) {
18372 if (values == null && mWindowManager != null) {
18373 // sentinel: fetch the current configuration from the window manager
18374 values = mWindowManager.computeNewConfiguration();
18377 if (mWindowManager != null) {
18378 mProcessList.applyDisplaySize(mWindowManager);
18381 final long origId = Binder.clearCallingIdentity();
18382 if (values != null) {
18383 Settings.System.clearConfiguration(values);
18385 updateConfigurationLocked(values, null, false);
18386 Binder.restoreCallingIdentity(origId);
18390 void updateUserConfigurationLocked() {
18391 Configuration configuration = new Configuration(mConfiguration);
18392 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18393 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18394 updateConfigurationLocked(configuration, null, false);
18397 boolean updateConfigurationLocked(Configuration values,
18398 ActivityRecord starting, boolean initLocale) {
18399 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18400 return updateConfigurationLocked(values, starting, initLocale, false,
18401 UserHandle.USER_NULL);
18404 // To cache the list of supported system locales
18405 private String[] mSupportedSystemLocales = null;
18408 * Do either or both things: (1) change the current configuration, and (2)
18409 * make sure the given activity is running with the (now) current
18410 * configuration. Returns true if the activity has been left running, or
18411 * false if <var>starting</var> is being destroyed to match the new
18414 * @param userId is only used when persistent parameter is set to true to persist configuration
18415 * for that particular user
18417 private boolean updateConfigurationLocked(Configuration values,
18418 ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18421 if (mWindowManager != null) {
18422 mWindowManager.deferSurfaceLayout();
18424 if (values != null) {
18425 Configuration newConfig = new Configuration(mConfiguration);
18426 changes = newConfig.updateFrom(values);
18427 if (changes != 0) {
18428 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18429 "Updating configuration to: " + values);
18431 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18433 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18434 final LocaleList locales = values.getLocales();
18435 int bestLocaleIndex = 0;
18436 if (locales.size() > 1) {
18437 if (mSupportedSystemLocales == null) {
18438 mSupportedSystemLocales =
18439 Resources.getSystem().getAssets().getLocales();
18441 bestLocaleIndex = Math.max(0,
18442 locales.getFirstMatchIndex(mSupportedSystemLocales));
18444 SystemProperties.set("persist.sys.locale",
18445 locales.get(bestLocaleIndex).toLanguageTag());
18446 LocaleList.setDefault(locales, bestLocaleIndex);
18447 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18448 locales.get(bestLocaleIndex)));
18451 mConfigurationSeq++;
18452 if (mConfigurationSeq <= 0) {
18453 mConfigurationSeq = 1;
18455 newConfig.seq = mConfigurationSeq;
18456 mConfiguration = newConfig;
18457 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18458 mUsageStatsService.reportConfigurationChange(newConfig,
18459 mUserController.getCurrentUserIdLocked());
18460 //mUsageStatsService.noteStartConfig(newConfig);
18462 final Configuration configCopy = new Configuration(mConfiguration);
18464 // TODO: If our config changes, should we auto dismiss any currently
18465 // showing dialogs?
18466 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18468 AttributeCache ac = AttributeCache.instance();
18470 ac.updateConfiguration(configCopy);
18473 // Make sure all resources in our process are updated
18474 // right now, so that anyone who is going to retrieve
18475 // resource values after we return will be sure to get
18476 // the new ones. This is especially important during
18477 // boot, where the first config change needs to guarantee
18478 // all resources have that config before following boot
18479 // code is executed.
18480 mSystemThread.applyConfigurationToResources(configCopy);
18482 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18483 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18484 msg.obj = new Configuration(configCopy);
18486 mHandler.sendMessage(msg);
18489 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18490 if (isDensityChange) {
18491 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18492 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18495 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18496 ProcessRecord app = mLruProcesses.get(i);
18498 if (app.thread != null) {
18499 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18500 + app.processName + " new config " + mConfiguration);
18501 app.thread.scheduleConfigurationChanged(configCopy);
18503 } catch (Exception e) {
18506 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18507 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18508 | Intent.FLAG_RECEIVER_REPLACE_PENDING
18509 | Intent.FLAG_RECEIVER_FOREGROUND);
18510 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18511 null, AppOpsManager.OP_NONE, null, false, false,
18512 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18513 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18514 // Tell the shortcut manager that the system locale changed. It needs to know
18515 // it before any other apps receive ACTION_LOCALE_CHANGED, which is why
18516 // we "push" from here, rather than having the service listen to the broadcast.
18517 final ShortcutServiceInternal shortcutService =
18518 LocalServices.getService(ShortcutServiceInternal.class);
18519 if (shortcutService != null) {
18520 shortcutService.onSystemLocaleChangedNoLock();
18523 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18524 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18525 if (!mProcessesReady) {
18526 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18528 broadcastIntentLocked(null, null, intent,
18529 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18530 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18533 // Update the configuration with WM first and check if any of the stacks need to be
18534 // resized due to the configuration change. If so, resize the stacks now and do any
18535 // relaunches if necessary. This way we don't need to relaunch again below in
18536 // ensureActivityConfigurationLocked().
18537 if (mWindowManager != null) {
18538 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
18539 if (resizedStacks != null) {
18540 for (int stackId : resizedStacks) {
18541 final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
18542 mStackSupervisor.resizeStackLocked(
18543 stackId, newBounds, null, null, false, false, !DEFER_RESUME);
18549 boolean kept = true;
18550 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18551 // mainStack is null during startup.
18552 if (mainStack != null) {
18553 if (changes != 0 && starting == null) {
18554 // If the configuration changed, and the caller is not already
18555 // in the process of starting an activity, then find the top
18556 // activity to check if its configuration needs to change.
18557 starting = mainStack.topRunningActivityLocked();
18560 if (starting != null) {
18561 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18562 // And we need to make sure at this point that all other activities
18563 // are made visible with the correct configuration.
18564 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18565 !PRESERVE_WINDOWS);
18568 if (mWindowManager != null) {
18569 mWindowManager.continueSurfaceLayout();
18575 * Decide based on the configuration whether we should shouw the ANR,
18576 * crash, etc dialogs. The idea is that if there is no affordnace to
18577 * press the on-screen buttons, we shouldn't show the dialog.
18579 * A thought: SystemUI might also want to get told about this, the Power
18580 * dialog / global actions also might want different behaviors.
18582 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18583 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18584 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18585 && config.navigation == Configuration.NAVIGATION_NONAV);
18586 final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18587 == Configuration.UI_MODE_TYPE_CAR);
18588 return inputMethodExists && uiIsNotCarType && !inVrMode;
18592 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18593 synchronized (this) {
18594 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18595 if (srec != null) {
18596 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18602 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18603 Intent resultData) {
18605 synchronized (this) {
18606 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18608 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18614 public int getLaunchedFromUid(IBinder activityToken) {
18615 ActivityRecord srec;
18616 synchronized (this) {
18617 srec = ActivityRecord.forTokenLocked(activityToken);
18619 if (srec == null) {
18622 return srec.launchedFromUid;
18625 public String getLaunchedFromPackage(IBinder activityToken) {
18626 ActivityRecord srec;
18627 synchronized (this) {
18628 srec = ActivityRecord.forTokenLocked(activityToken);
18630 if (srec == null) {
18633 return srec.launchedFromPackage;
18636 // =========================================================
18637 // LIFETIME MANAGEMENT
18638 // =========================================================
18640 // Returns which broadcast queue the app is the current [or imminent] receiver
18641 // on, or 'null' if the app is not an active broadcast recipient.
18642 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18643 BroadcastRecord r = app.curReceiver;
18648 // It's not the current receiver, but it might be starting up to become one
18649 synchronized (this) {
18650 for (BroadcastQueue queue : mBroadcastQueues) {
18651 r = queue.mPendingBroadcast;
18652 if (r != null && r.curApp == app) {
18653 // found it; report which queue it's in
18662 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
18663 int targetUid, ComponentName targetComponent, String targetProcess) {
18664 if (!mTrackingAssociations) {
18667 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18668 = mAssociations.get(targetUid);
18669 if (components == null) {
18670 components = new ArrayMap<>();
18671 mAssociations.put(targetUid, components);
18673 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18674 if (sourceUids == null) {
18675 sourceUids = new SparseArray<>();
18676 components.put(targetComponent, sourceUids);
18678 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18679 if (sourceProcesses == null) {
18680 sourceProcesses = new ArrayMap<>();
18681 sourceUids.put(sourceUid, sourceProcesses);
18683 Association ass = sourceProcesses.get(sourceProcess);
18685 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18687 sourceProcesses.put(sourceProcess, ass);
18691 if (ass.mNesting == 1) {
18692 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
18693 ass.mLastState = sourceState;
18698 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18699 ComponentName targetComponent) {
18700 if (!mTrackingAssociations) {
18703 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18704 = mAssociations.get(targetUid);
18705 if (components == null) {
18708 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18709 if (sourceUids == null) {
18712 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18713 if (sourceProcesses == null) {
18716 Association ass = sourceProcesses.get(sourceProcess);
18717 if (ass == null || ass.mNesting <= 0) {
18721 if (ass.mNesting == 0) {
18722 long uptime = SystemClock.uptimeMillis();
18723 ass.mTime += uptime - ass.mStartTime;
18724 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18725 += uptime - ass.mLastStateUptime;
18726 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
18730 private void noteUidProcessState(final int uid, final int state) {
18731 mBatteryStatsService.noteUidProcessState(uid, state);
18732 if (mTrackingAssociations) {
18733 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
18734 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
18735 = mAssociations.valueAt(i1);
18736 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
18737 SparseArray<ArrayMap<String, Association>> sourceUids
18738 = targetComponents.valueAt(i2);
18739 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
18740 if (sourceProcesses != null) {
18741 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
18742 Association ass = sourceProcesses.valueAt(i4);
18743 if (ass.mNesting >= 1) {
18744 // currently associated
18745 long uptime = SystemClock.uptimeMillis();
18746 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
18747 += uptime - ass.mLastStateUptime;
18748 ass.mLastState = state;
18749 ass.mLastStateUptime = uptime;
18758 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18759 boolean doingAll, long now) {
18760 if (mAdjSeq == app.adjSeq) {
18761 // This adjustment has already been computed.
18762 return app.curRawAdj;
18765 if (app.thread == null) {
18766 app.adjSeq = mAdjSeq;
18767 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18768 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18769 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18772 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18773 app.adjSource = null;
18774 app.adjTarget = null;
18776 app.cached = false;
18778 final int activitiesSize = app.activities.size();
18780 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18781 // The max adjustment doesn't allow this app to be anything
18782 // below foreground, so it is not worth doing work for it.
18783 app.adjType = "fixed";
18784 app.adjSeq = mAdjSeq;
18785 app.curRawAdj = app.maxAdj;
18786 app.foregroundActivities = false;
18787 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18788 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18789 // System processes can do UI, and when they do we want to have
18790 // them trim their memory after the user leaves the UI. To
18791 // facilitate this, here we need to determine whether or not it
18792 // is currently showing UI.
18793 app.systemNoUi = true;
18794 if (app == TOP_APP) {
18795 app.systemNoUi = false;
18796 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18797 app.adjType = "pers-top-activity";
18798 } else if (activitiesSize > 0) {
18799 for (int j = 0; j < activitiesSize; j++) {
18800 final ActivityRecord r = app.activities.get(j);
18802 app.systemNoUi = false;
18806 if (!app.systemNoUi) {
18807 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18809 return (app.curAdj=app.maxAdj);
18812 app.systemNoUi = false;
18814 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18816 // Determine the importance of the process, starting with most
18817 // important to least, and assign an appropriate OOM adjustment.
18821 boolean foregroundActivities = false;
18822 BroadcastQueue queue;
18823 if (app == TOP_APP) {
18824 // The last app on the list is the foreground app.
18825 adj = ProcessList.FOREGROUND_APP_ADJ;
18826 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18827 app.adjType = "top-activity";
18828 foregroundActivities = true;
18829 procState = PROCESS_STATE_CUR_TOP;
18830 } else if (app.instrumentationClass != null) {
18831 // Don't want to kill running instrumentation.
18832 adj = ProcessList.FOREGROUND_APP_ADJ;
18833 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18834 app.adjType = "instrumentation";
18835 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18836 } else if ((queue = isReceivingBroadcast(app)) != null) {
18837 // An app that is currently receiving a broadcast also
18838 // counts as being in the foreground for OOM killer purposes.
18839 // It's placed in a sched group based on the nature of the
18840 // broadcast as reflected by which queue it's active in.
18841 adj = ProcessList.FOREGROUND_APP_ADJ;
18842 schedGroup = (queue == mFgBroadcastQueue)
18843 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18844 app.adjType = "broadcast";
18845 procState = ActivityManager.PROCESS_STATE_RECEIVER;
18846 } else if (app.executingServices.size() > 0) {
18847 // An app that is currently executing a service callback also
18848 // counts as being in the foreground.
18849 adj = ProcessList.FOREGROUND_APP_ADJ;
18850 schedGroup = app.execServicesFg ?
18851 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18852 app.adjType = "exec-service";
18853 procState = ActivityManager.PROCESS_STATE_SERVICE;
18854 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18856 // As far as we know the process is empty. We may change our mind later.
18857 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18858 // At this point we don't actually know the adjustment. Use the cached adj
18859 // value that the caller wants us to.
18861 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18864 app.adjType = "cch-empty";
18867 // Examine all activities if not already foreground.
18868 if (!foregroundActivities && activitiesSize > 0) {
18869 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18870 for (int j = 0; j < activitiesSize; j++) {
18871 final ActivityRecord r = app.activities.get(j);
18872 if (r.app != app) {
18873 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
18874 + " instead of expected " + app);
18875 if (r.app == null || (r.app.uid == app.uid)) {
18876 // Only fix things up when they look sane
18883 // App has a visible activity; only upgrade adjustment.
18884 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18885 adj = ProcessList.VISIBLE_APP_ADJ;
18886 app.adjType = "visible";
18888 if (procState > PROCESS_STATE_CUR_TOP) {
18889 procState = PROCESS_STATE_CUR_TOP;
18891 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18892 app.cached = false;
18894 foregroundActivities = true;
18895 if (r.task != null && minLayer > 0) {
18896 final int layer = r.task.mLayerRank;
18897 if (layer >= 0 && minLayer > layer) {
18902 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18903 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18904 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18905 app.adjType = "pausing";
18907 if (procState > PROCESS_STATE_CUR_TOP) {
18908 procState = PROCESS_STATE_CUR_TOP;
18910 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18911 app.cached = false;
18913 foregroundActivities = true;
18914 } else if (r.state == ActivityState.STOPPING) {
18915 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18916 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18917 app.adjType = "stopping";
18919 // For the process state, we will at this point consider the
18920 // process to be cached. It will be cached either as an activity
18921 // or empty depending on whether the activity is finishing. We do
18922 // this so that we can treat the process as cached for purposes of
18923 // memory trimming (determing current memory level, trim command to
18924 // send to process) since there can be an arbitrary number of stopping
18925 // processes and they should soon all go into the cached state.
18926 if (!r.finishing) {
18927 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18928 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18931 app.cached = false;
18933 foregroundActivities = true;
18935 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18936 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18937 app.adjType = "cch-act";
18941 if (adj == ProcessList.VISIBLE_APP_ADJ) {
18946 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18947 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18948 if (app.foregroundServices) {
18949 // The user is aware of this app, so make it visible.
18950 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18951 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18952 app.cached = false;
18953 app.adjType = "fg-service";
18954 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18955 } else if (app.forcingToForeground != null) {
18956 // The user is aware of this app, so make it visible.
18957 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18958 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18959 app.cached = false;
18960 app.adjType = "force-fg";
18961 app.adjSource = app.forcingToForeground;
18962 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18966 if (app == mHeavyWeightProcess) {
18967 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18968 // We don't want to kill the current heavy-weight process.
18969 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18970 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18971 app.cached = false;
18972 app.adjType = "heavy";
18974 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18975 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18979 if (app == mHomeProcess) {
18980 if (adj > ProcessList.HOME_APP_ADJ) {
18981 // This process is hosting what we currently consider to be the
18982 // home app, so we don't want to let it go into the background.
18983 adj = ProcessList.HOME_APP_ADJ;
18984 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18985 app.cached = false;
18986 app.adjType = "home";
18988 if (procState > ActivityManager.PROCESS_STATE_HOME) {
18989 procState = ActivityManager.PROCESS_STATE_HOME;
18993 if (app == mPreviousProcess && app.activities.size() > 0) {
18994 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18995 // This was the previous process that showed UI to the user.
18996 // We want to try to keep it around more aggressively, to give
18997 // a good experience around switching between two apps.
18998 adj = ProcessList.PREVIOUS_APP_ADJ;
18999 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19000 app.cached = false;
19001 app.adjType = "previous";
19003 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19004 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19008 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19009 + " reason=" + app.adjType);
19011 // By default, we use the computed adjustment. It may be changed if
19012 // there are applications dependent on our services or providers, but
19013 // this gives us a baseline and makes sure we don't get into an
19014 // infinite recursion.
19015 app.adjSeq = mAdjSeq;
19016 app.curRawAdj = adj;
19017 app.hasStartedServices = false;
19019 if (mBackupTarget != null && app == mBackupTarget.app) {
19020 // If possible we want to avoid killing apps while they're being backed up
19021 if (adj > ProcessList.BACKUP_APP_ADJ) {
19022 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19023 adj = ProcessList.BACKUP_APP_ADJ;
19024 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19025 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19027 app.adjType = "backup";
19028 app.cached = false;
19030 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19031 procState = ActivityManager.PROCESS_STATE_BACKUP;
19035 boolean mayBeTop = false;
19037 for (int is = app.services.size()-1;
19038 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19039 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19040 || procState > ActivityManager.PROCESS_STATE_TOP);
19042 ServiceRecord s = app.services.valueAt(is);
19043 if (s.startRequested) {
19044 app.hasStartedServices = true;
19045 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19046 procState = ActivityManager.PROCESS_STATE_SERVICE;
19048 if (app.hasShownUi && app != mHomeProcess) {
19049 // If this process has shown some UI, let it immediately
19050 // go to the LRU list because it may be pretty heavy with
19051 // UI stuff. We'll tag it with a label just to help
19052 // debug and understand what is going on.
19053 if (adj > ProcessList.SERVICE_ADJ) {
19054 app.adjType = "cch-started-ui-services";
19057 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19058 // This service has seen some activity within
19059 // recent memory, so we will keep its process ahead
19060 // of the background processes.
19061 if (adj > ProcessList.SERVICE_ADJ) {
19062 adj = ProcessList.SERVICE_ADJ;
19063 app.adjType = "started-services";
19064 app.cached = false;
19067 // If we have let the service slide into the background
19068 // state, still have some text describing what it is doing
19069 // even though the service no longer has an impact.
19070 if (adj > ProcessList.SERVICE_ADJ) {
19071 app.adjType = "cch-started-services";
19076 app.whitelistManager = false;
19078 for (int conni = s.connections.size()-1;
19079 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19080 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19081 || procState > ActivityManager.PROCESS_STATE_TOP);
19083 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19085 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19086 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19087 || procState > ActivityManager.PROCESS_STATE_TOP);
19089 // XXX should compute this based on the max of
19090 // all connected clients.
19091 ConnectionRecord cr = clist.get(i);
19092 if (cr.binding.client == app) {
19093 // Binding to ourself is not interesting.
19096 if ((cr.flags & Context.BIND_ALLOW_WHITELIST_MANAGEMENT) != 0) {
19097 app.whitelistManager = true;
19100 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19101 ProcessRecord client = cr.binding.client;
19102 int clientAdj = computeOomAdjLocked(client, cachedAdj,
19103 TOP_APP, doingAll, now);
19104 int clientProcState = client.curProcState;
19105 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19106 // If the other app is cached for any reason, for purposes here
19107 // we are going to consider it empty. The specific cached state
19108 // doesn't propagate except under certain conditions.
19109 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19111 String adjType = null;
19112 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19113 // Not doing bind OOM management, so treat
19114 // this guy more like a started service.
19115 if (app.hasShownUi && app != mHomeProcess) {
19116 // If this process has shown some UI, let it immediately
19117 // go to the LRU list because it may be pretty heavy with
19118 // UI stuff. We'll tag it with a label just to help
19119 // debug and understand what is going on.
19120 if (adj > clientAdj) {
19121 adjType = "cch-bound-ui-services";
19123 app.cached = false;
19125 clientProcState = procState;
19127 if (now >= (s.lastActivity
19128 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19129 // This service has not seen activity within
19130 // recent memory, so allow it to drop to the
19131 // LRU list if there is no other reason to keep
19132 // it around. We'll also tag it with a label just
19133 // to help debug and undertand what is going on.
19134 if (adj > clientAdj) {
19135 adjType = "cch-bound-services";
19141 if (adj > clientAdj) {
19142 // If this process has recently shown UI, and
19143 // the process that is binding to it is less
19144 // important than being visible, then we don't
19145 // care about the binding as much as we care
19146 // about letting this process get into the LRU
19147 // list to be killed and restarted if needed for
19149 if (app.hasShownUi && app != mHomeProcess
19150 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19151 adjType = "cch-bound-ui-services";
19153 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19154 |Context.BIND_IMPORTANT)) != 0) {
19155 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19156 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19157 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19158 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19159 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19160 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19161 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19164 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19165 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19168 if (!client.cached) {
19169 app.cached = false;
19171 adjType = "service";
19174 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19175 // This will treat important bound services identically to
19176 // the top app, which may behave differently than generic
19177 // foreground work.
19178 if (client.curSchedGroup > schedGroup) {
19179 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19180 schedGroup = client.curSchedGroup;
19182 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19185 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19186 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19187 // Special handling of clients who are in the top state.
19188 // We *may* want to consider this process to be in the
19189 // top state as well, but only if there is not another
19190 // reason for it to be running. Being on the top is a
19191 // special state, meaning you are specifically running
19192 // for the current top app. If the process is already
19193 // running in the background for some other reason, it
19194 // is more important to continue considering it to be
19195 // in the background state.
19197 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19199 // Special handling for above-top states (persistent
19200 // processes). These should not bring the current process
19201 // into the top state, since they are not on top. Instead
19202 // give them the best state after that.
19203 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19205 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19206 } else if (mWakefulness
19207 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19208 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19211 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19214 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19219 if (clientProcState <
19220 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19222 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19225 if (procState > clientProcState) {
19226 procState = clientProcState;
19228 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19229 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19230 app.pendingUiClean = true;
19232 if (adjType != null) {
19233 app.adjType = adjType;
19234 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19235 .REASON_SERVICE_IN_USE;
19236 app.adjSource = cr.binding.client;
19237 app.adjSourceProcState = clientProcState;
19238 app.adjTarget = s.name;
19241 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19242 app.treatLikeActivity = true;
19244 final ActivityRecord a = cr.activity;
19245 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19246 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19247 (a.visible || a.state == ActivityState.RESUMED ||
19248 a.state == ActivityState.PAUSING)) {
19249 adj = ProcessList.FOREGROUND_APP_ADJ;
19250 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19251 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19252 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19254 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19257 app.cached = false;
19258 app.adjType = "service";
19259 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19260 .REASON_SERVICE_IN_USE;
19262 app.adjSourceProcState = procState;
19263 app.adjTarget = s.name;
19270 for (int provi = app.pubProviders.size()-1;
19271 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19272 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19273 || procState > ActivityManager.PROCESS_STATE_TOP);
19275 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19276 for (int i = cpr.connections.size()-1;
19277 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19278 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19279 || procState > ActivityManager.PROCESS_STATE_TOP);
19281 ContentProviderConnection conn = cpr.connections.get(i);
19282 ProcessRecord client = conn.client;
19283 if (client == app) {
19284 // Being our own client is not interesting.
19287 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19288 int clientProcState = client.curProcState;
19289 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19290 // If the other app is cached for any reason, for purposes here
19291 // we are going to consider it empty.
19292 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19294 if (adj > clientAdj) {
19295 if (app.hasShownUi && app != mHomeProcess
19296 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19297 app.adjType = "cch-ui-provider";
19299 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19300 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19301 app.adjType = "provider";
19303 app.cached &= client.cached;
19304 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19305 .REASON_PROVIDER_IN_USE;
19306 app.adjSource = client;
19307 app.adjSourceProcState = clientProcState;
19308 app.adjTarget = cpr.name;
19310 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19311 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19312 // Special handling of clients who are in the top state.
19313 // We *may* want to consider this process to be in the
19314 // top state as well, but only if there is not another
19315 // reason for it to be running. Being on the top is a
19316 // special state, meaning you are specifically running
19317 // for the current top app. If the process is already
19318 // running in the background for some other reason, it
19319 // is more important to continue considering it to be
19320 // in the background state.
19322 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19324 // Special handling for above-top states (persistent
19325 // processes). These should not bring the current process
19326 // into the top state, since they are not on top. Instead
19327 // give them the best state after that.
19329 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19332 if (procState > clientProcState) {
19333 procState = clientProcState;
19335 if (client.curSchedGroup > schedGroup) {
19336 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19339 // If the provider has external (non-framework) process
19340 // dependencies, ensure that its adjustment is at least
19341 // FOREGROUND_APP_ADJ.
19342 if (cpr.hasExternalProcessHandles()) {
19343 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19344 adj = ProcessList.FOREGROUND_APP_ADJ;
19345 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19346 app.cached = false;
19347 app.adjType = "provider";
19348 app.adjTarget = cpr.name;
19350 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19351 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19356 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19357 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19358 adj = ProcessList.PREVIOUS_APP_ADJ;
19359 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19360 app.cached = false;
19361 app.adjType = "provider";
19363 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19364 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19368 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19369 // A client of one of our services or providers is in the top state. We
19370 // *may* want to be in the top state, but not if we are already running in
19371 // the background for some other reason. For the decision here, we are going
19372 // to pick out a few specific states that we want to remain in when a client
19373 // is top (states that tend to be longer-term) and otherwise allow it to go
19374 // to the top state.
19375 switch (procState) {
19376 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19377 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19378 case ActivityManager.PROCESS_STATE_SERVICE:
19379 // These all are longer-term states, so pull them up to the top
19380 // of the background states, but not all the way to the top state.
19381 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19384 // Otherwise, top is a better choice, so take it.
19385 procState = ActivityManager.PROCESS_STATE_TOP;
19390 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19391 if (app.hasClientActivities) {
19392 // This is a cached process, but with client activities. Mark it so.
19393 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19394 app.adjType = "cch-client-act";
19395 } else if (app.treatLikeActivity) {
19396 // This is a cached process, but somebody wants us to treat it like it has
19397 // an activity, okay!
19398 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19399 app.adjType = "cch-as-act";
19403 if (adj == ProcessList.SERVICE_ADJ) {
19405 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19406 mNewNumServiceProcs++;
19407 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19408 if (!app.serviceb) {
19409 // This service isn't far enough down on the LRU list to
19410 // normally be a B service, but if we are low on RAM and it
19411 // is large we want to force it down since we would prefer to
19412 // keep launcher over it.
19413 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19414 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19415 app.serviceHighRam = true;
19416 app.serviceb = true;
19417 //Slog.i(TAG, "ADJ " + app + " high ram!");
19419 mNewNumAServiceProcs++;
19420 //Slog.i(TAG, "ADJ " + app + " not high ram!");
19423 app.serviceHighRam = false;
19426 if (app.serviceb) {
19427 adj = ProcessList.SERVICE_B_ADJ;
19431 app.curRawAdj = adj;
19433 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19434 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19435 if (adj > app.maxAdj) {
19437 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19438 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19442 // Do final modification to adj. Everything we do between here and applying
19443 // the final setAdj must be done in this function, because we will also use
19444 // it when computing the final cached adj later. Note that we don't need to
19445 // worry about this for max adj above, since max adj will always be used to
19446 // keep it out of the cached vaues.
19447 app.curAdj = app.modifyRawOomAdj(adj);
19448 app.curSchedGroup = schedGroup;
19449 app.curProcState = procState;
19450 app.foregroundActivities = foregroundActivities;
19452 return app.curRawAdj;
19456 * Record new PSS sample for a process.
19458 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19460 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19462 proc.lastPssTime = now;
19463 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19464 if (DEBUG_PSS) Slog.d(TAG_PSS,
19465 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19466 + " state=" + ProcessList.makeProcStateString(procState));
19467 if (proc.initialIdlePss == 0) {
19468 proc.initialIdlePss = pss;
19470 proc.lastPss = pss;
19471 proc.lastSwapPss = swapPss;
19472 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19473 proc.lastCachedPss = pss;
19474 proc.lastCachedSwapPss = swapPss;
19477 final SparseArray<Pair<Long, String>> watchUids
19478 = mMemWatchProcesses.getMap().get(proc.processName);
19480 if (watchUids != null) {
19481 Pair<Long, String> val = watchUids.get(proc.uid);
19483 val = watchUids.get(0);
19489 if (check != null) {
19490 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19491 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19492 if (!isDebuggable) {
19493 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19494 isDebuggable = true;
19497 if (isDebuggable) {
19498 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19499 final ProcessRecord myProc = proc;
19500 final File heapdumpFile = DumpHeapProvider.getJavaFile();
19501 mMemWatchDumpProcName = proc.processName;
19502 mMemWatchDumpFile = heapdumpFile.toString();
19503 mMemWatchDumpPid = proc.pid;
19504 mMemWatchDumpUid = proc.uid;
19505 BackgroundThread.getHandler().post(new Runnable() {
19507 public void run() {
19508 revokeUriPermission(ActivityThread.currentActivityThread()
19509 .getApplicationThread(),
19510 DumpHeapActivity.JAVA_URI,
19511 Intent.FLAG_GRANT_READ_URI_PERMISSION
19512 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19513 UserHandle.myUserId());
19514 ParcelFileDescriptor fd = null;
19516 heapdumpFile.delete();
19517 fd = ParcelFileDescriptor.open(heapdumpFile,
19518 ParcelFileDescriptor.MODE_CREATE |
19519 ParcelFileDescriptor.MODE_TRUNCATE |
19520 ParcelFileDescriptor.MODE_WRITE_ONLY |
19521 ParcelFileDescriptor.MODE_APPEND);
19522 IApplicationThread thread = myProc.thread;
19523 if (thread != null) {
19525 if (DEBUG_PSS) Slog.d(TAG_PSS,
19526 "Requesting dump heap from "
19527 + myProc + " to " + heapdumpFile);
19528 thread.dumpHeap(true, heapdumpFile.toString(), fd);
19529 } catch (RemoteException e) {
19532 } catch (FileNotFoundException e) {
19533 e.printStackTrace();
19538 } catch (IOException e) {
19545 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19546 + ", but debugging not enabled");
19553 * Schedule PSS collection of a process.
19555 void requestPssLocked(ProcessRecord proc, int procState) {
19556 if (mPendingPssProcesses.contains(proc)) {
19559 if (mPendingPssProcesses.size() == 0) {
19560 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19562 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19563 proc.pssProcState = procState;
19564 mPendingPssProcesses.add(proc);
19568 * Schedule PSS collection of all processes.
19570 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19572 if (now < (mLastFullPssTime +
19573 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19577 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
19578 mLastFullPssTime = now;
19579 mFullPssPending = true;
19580 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19581 mPendingPssProcesses.clear();
19582 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19583 ProcessRecord app = mLruProcesses.get(i);
19584 if (app.thread == null
19585 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19588 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19589 app.pssProcState = app.setProcState;
19590 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19591 mTestPssMode, isSleeping(), now);
19592 mPendingPssProcesses.add(app);
19595 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19598 public void setTestPssMode(boolean enabled) {
19599 synchronized (this) {
19600 mTestPssMode = enabled;
19602 // Whenever we enable the mode, we want to take a snapshot all of current
19603 // process mem use.
19604 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19610 * Ask a given process to GC right now.
19612 final void performAppGcLocked(ProcessRecord app) {
19614 app.lastRequestedGc = SystemClock.uptimeMillis();
19615 if (app.thread != null) {
19616 if (app.reportLowMemory) {
19617 app.reportLowMemory = false;
19618 app.thread.scheduleLowMemory();
19620 app.thread.processInBackground();
19623 } catch (Exception e) {
19629 * Returns true if things are idle enough to perform GCs.
19631 private final boolean canGcNowLocked() {
19632 boolean processingBroadcasts = false;
19633 for (BroadcastQueue q : mBroadcastQueues) {
19634 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19635 processingBroadcasts = true;
19638 return !processingBroadcasts
19639 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19643 * Perform GCs on all processes that are waiting for it, but only
19644 * if things are idle.
19646 final void performAppGcsLocked() {
19647 final int N = mProcessesToGc.size();
19651 if (canGcNowLocked()) {
19652 while (mProcessesToGc.size() > 0) {
19653 ProcessRecord proc = mProcessesToGc.remove(0);
19654 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19655 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19656 <= SystemClock.uptimeMillis()) {
19657 // To avoid spamming the system, we will GC processes one
19658 // at a time, waiting a few seconds between each.
19659 performAppGcLocked(proc);
19660 scheduleAppGcsLocked();
19663 // It hasn't been long enough since we last GCed this
19664 // process... put it in the list to wait for its time.
19665 addProcessToGcListLocked(proc);
19671 scheduleAppGcsLocked();
19676 * If all looks good, perform GCs on all processes waiting for them.
19678 final void performAppGcsIfAppropriateLocked() {
19679 if (canGcNowLocked()) {
19680 performAppGcsLocked();
19683 // Still not idle, wait some more.
19684 scheduleAppGcsLocked();
19688 * Schedule the execution of all pending app GCs.
19690 final void scheduleAppGcsLocked() {
19691 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19693 if (mProcessesToGc.size() > 0) {
19694 // Schedule a GC for the time to the next process.
19695 ProcessRecord proc = mProcessesToGc.get(0);
19696 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19698 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19699 long now = SystemClock.uptimeMillis();
19700 if (when < (now+GC_TIMEOUT)) {
19701 when = now + GC_TIMEOUT;
19703 mHandler.sendMessageAtTime(msg, when);
19708 * Add a process to the array of processes waiting to be GCed. Keeps the
19709 * list in sorted order by the last GC time. The process can't already be
19712 final void addProcessToGcListLocked(ProcessRecord proc) {
19713 boolean added = false;
19714 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19715 if (mProcessesToGc.get(i).lastRequestedGc <
19716 proc.lastRequestedGc) {
19718 mProcessesToGc.add(i+1, proc);
19723 mProcessesToGc.add(0, proc);
19728 * Set up to ask a process to GC itself. This will either do it
19729 * immediately, or put it on the list of processes to gc the next
19730 * time things are idle.
19732 final void scheduleAppGcLocked(ProcessRecord app) {
19733 long now = SystemClock.uptimeMillis();
19734 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19737 if (!mProcessesToGc.contains(app)) {
19738 addProcessToGcListLocked(app);
19739 scheduleAppGcsLocked();
19743 final void checkExcessivePowerUsageLocked(boolean doKills) {
19744 updateCpuStatsNow();
19746 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19747 boolean doWakeKills = doKills;
19748 boolean doCpuKills = doKills;
19749 if (mLastPowerCheckRealtime == 0) {
19750 doWakeKills = false;
19752 if (mLastPowerCheckUptime == 0) {
19753 doCpuKills = false;
19755 if (stats.isScreenOn()) {
19756 doWakeKills = false;
19758 final long curRealtime = SystemClock.elapsedRealtime();
19759 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19760 final long curUptime = SystemClock.uptimeMillis();
19761 final long uptimeSince = curUptime - mLastPowerCheckUptime;
19762 mLastPowerCheckRealtime = curRealtime;
19763 mLastPowerCheckUptime = curUptime;
19764 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19765 doWakeKills = false;
19767 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19768 doCpuKills = false;
19770 int i = mLruProcesses.size();
19773 ProcessRecord app = mLruProcesses.get(i);
19774 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19776 synchronized (stats) {
19777 wtime = stats.getProcessWakeTime(app.info.uid,
19778 app.pid, curRealtime);
19780 long wtimeUsed = wtime - app.lastWakeTime;
19781 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19783 StringBuilder sb = new StringBuilder(128);
19784 sb.append("Wake for ");
19785 app.toShortString(sb);
19786 sb.append(": over ");
19787 TimeUtils.formatDuration(realtimeSince, sb);
19788 sb.append(" used ");
19789 TimeUtils.formatDuration(wtimeUsed, sb);
19791 sb.append((wtimeUsed*100)/realtimeSince);
19793 Slog.i(TAG_POWER, sb.toString());
19795 sb.append("CPU for ");
19796 app.toShortString(sb);
19797 sb.append(": over ");
19798 TimeUtils.formatDuration(uptimeSince, sb);
19799 sb.append(" used ");
19800 TimeUtils.formatDuration(cputimeUsed, sb);
19802 sb.append((cputimeUsed*100)/uptimeSince);
19804 Slog.i(TAG_POWER, sb.toString());
19806 // If a process has held a wake lock for more
19807 // than 50% of the time during this period,
19808 // that sounds bad. Kill!
19809 if (doWakeKills && realtimeSince > 0
19810 && ((wtimeUsed*100)/realtimeSince) >= 50) {
19811 synchronized (stats) {
19812 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19813 realtimeSince, wtimeUsed);
19815 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19816 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19817 } else if (doCpuKills && uptimeSince > 0
19818 && ((cputimeUsed*100)/uptimeSince) >= 25) {
19819 synchronized (stats) {
19820 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19821 uptimeSince, cputimeUsed);
19823 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19824 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19826 app.lastWakeTime = wtime;
19827 app.lastCpuTime = app.curCpuTime;
19833 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19835 boolean success = true;
19837 if (app.curRawAdj != app.setRawAdj) {
19838 app.setRawAdj = app.curRawAdj;
19843 if (app.curAdj != app.setAdj) {
19844 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19845 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19846 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19848 app.setAdj = app.curAdj;
19851 if (app.setSchedGroup != app.curSchedGroup) {
19852 app.setSchedGroup = app.curSchedGroup;
19853 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19854 "Setting sched group of " + app.processName
19855 + " to " + app.curSchedGroup);
19856 if (app.waitingToKill != null && app.curReceiver == null
19857 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19858 app.kill(app.waitingToKill, true);
19862 switch (app.curSchedGroup) {
19863 case ProcessList.SCHED_GROUP_BACKGROUND:
19864 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19866 case ProcessList.SCHED_GROUP_TOP_APP:
19867 processGroup = Process.THREAD_GROUP_TOP_APP;
19870 processGroup = Process.THREAD_GROUP_DEFAULT;
19874 long oldId = Binder.clearCallingIdentity();
19876 Process.setProcessGroup(app.pid, processGroup);
19877 } catch (Exception e) {
19878 Slog.w(TAG, "Failed setting process group of " + app.pid
19879 + " to " + app.curSchedGroup);
19880 e.printStackTrace();
19882 Binder.restoreCallingIdentity(oldId);
19885 if (app.thread != null) {
19887 app.thread.setSchedulingGroup(processGroup);
19888 } catch (RemoteException e) {
19894 if (app.repForegroundActivities != app.foregroundActivities) {
19895 app.repForegroundActivities = app.foregroundActivities;
19896 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19898 if (app.repProcState != app.curProcState) {
19899 app.repProcState = app.curProcState;
19900 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19901 if (app.thread != null) {
19904 //RuntimeException h = new RuntimeException("here");
19905 Slog.i(TAG, "Sending new process state " + app.repProcState
19906 + " to " + app /*, h*/);
19908 app.thread.setProcessState(app.repProcState);
19909 } catch (RemoteException e) {
19913 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19914 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19915 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19916 // Experimental code to more aggressively collect pss while
19917 // running test... the problem is that this tends to collect
19918 // the data right when a process is transitioning between process
19919 // states, which well tend to give noisy data.
19920 long start = SystemClock.uptimeMillis();
19921 long pss = Debug.getPss(app.pid, mTmpLong, null);
19922 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19923 mPendingPssProcesses.remove(app);
19924 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19925 + " to " + app.curProcState + ": "
19926 + (SystemClock.uptimeMillis()-start) + "ms");
19928 app.lastStateTime = now;
19929 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19930 mTestPssMode, isSleeping(), now);
19931 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19932 + ProcessList.makeProcStateString(app.setProcState) + " to "
19933 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19934 + (app.nextPssTime-now) + ": " + app);
19936 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19937 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19939 requestPssLocked(app, app.setProcState);
19940 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19941 mTestPssMode, isSleeping(), now);
19942 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19943 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19945 if (app.setProcState != app.curProcState) {
19946 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19947 "Proc state change of " + app.processName
19948 + " to " + app.curProcState);
19949 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19950 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19951 if (setImportant && !curImportant) {
19952 // This app is no longer something we consider important enough to allow to
19953 // use arbitrary amounts of battery power. Note
19954 // its current wake lock time to later know to kill it if
19955 // it is not behaving well.
19956 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19957 synchronized (stats) {
19958 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19959 app.pid, nowElapsed);
19961 app.lastCpuTime = app.curCpuTime;
19964 // Inform UsageStats of important process state change
19965 // Must be called before updating setProcState
19966 maybeUpdateUsageStatsLocked(app, nowElapsed);
19968 app.setProcState = app.curProcState;
19969 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19970 app.notCachedSinceIdle = false;
19973 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19975 app.procStateChanged = true;
19977 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19978 > USAGE_STATS_INTERACTION_INTERVAL) {
19979 // For apps that sit around for a long time in the interactive state, we need
19980 // to report this at least once a day so they don't go idle.
19981 maybeUpdateUsageStatsLocked(app, nowElapsed);
19984 if (changes != 0) {
19985 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19986 "Changes in " + app + ": " + changes);
19987 int i = mPendingProcessChanges.size()-1;
19988 ProcessChangeItem item = null;
19990 item = mPendingProcessChanges.get(i);
19991 if (item.pid == app.pid) {
19992 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19993 "Re-using existing item: " + item);
19999 // No existing item in pending changes; need a new one.
20000 final int NA = mAvailProcessChanges.size();
20002 item = mAvailProcessChanges.remove(NA-1);
20003 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20004 "Retrieving available item: " + item);
20006 item = new ProcessChangeItem();
20007 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20008 "Allocating new item: " + item);
20011 item.pid = app.pid;
20012 item.uid = app.info.uid;
20013 if (mPendingProcessChanges.size() == 0) {
20014 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20015 "*** Enqueueing dispatch processes changed!");
20016 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20018 mPendingProcessChanges.add(item);
20020 item.changes |= changes;
20021 item.processState = app.repProcState;
20022 item.foregroundActivities = app.repForegroundActivities;
20023 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20024 "Item " + Integer.toHexString(System.identityHashCode(item))
20025 + " " + app.toShortString() + ": changes=" + item.changes
20026 + " procState=" + item.processState
20027 + " foreground=" + item.foregroundActivities
20028 + " type=" + app.adjType + " source=" + app.adjSource
20029 + " target=" + app.adjTarget);
20035 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20036 final UidRecord.ChangeItem pendingChange;
20037 if (uidRec == null || uidRec.pendingChange == null) {
20038 if (mPendingUidChanges.size() == 0) {
20039 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20040 "*** Enqueueing dispatch uid changed!");
20041 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20043 final int NA = mAvailUidChanges.size();
20045 pendingChange = mAvailUidChanges.remove(NA-1);
20046 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20047 "Retrieving available item: " + pendingChange);
20049 pendingChange = new UidRecord.ChangeItem();
20050 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20051 "Allocating new item: " + pendingChange);
20053 if (uidRec != null) {
20054 uidRec.pendingChange = pendingChange;
20055 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20056 // If this uid is going away, and we haven't yet reported it is gone,
20058 change = UidRecord.CHANGE_GONE_IDLE;
20060 } else if (uid < 0) {
20061 throw new IllegalArgumentException("No UidRecord or uid");
20063 pendingChange.uidRecord = uidRec;
20064 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20065 mPendingUidChanges.add(pendingChange);
20067 pendingChange = uidRec.pendingChange;
20068 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20069 change = UidRecord.CHANGE_GONE_IDLE;
20072 pendingChange.change = change;
20073 pendingChange.processState = uidRec != null
20074 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20077 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20078 String authority) {
20079 if (app == null) return;
20080 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20081 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20082 if (userState == null) return;
20083 final long now = SystemClock.elapsedRealtime();
20084 Long lastReported = userState.mProviderLastReportedFg.get(authority);
20085 if (lastReported == null || lastReported < now - 60 * 1000L) {
20086 mUsageStatsService.reportContentProviderUsage(
20087 authority, providerPkgName, app.userId);
20088 userState.mProviderLastReportedFg.put(authority, now);
20093 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20094 if (DEBUG_USAGE_STATS) {
20095 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20096 + "] state changes: old = " + app.setProcState + ", new = "
20097 + app.curProcState);
20099 if (mUsageStatsService == null) {
20102 boolean isInteraction;
20103 // To avoid some abuse patterns, we are going to be careful about what we consider
20104 // to be an app interaction. Being the top activity doesn't count while the display
20105 // is sleeping, nor do short foreground services.
20106 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20107 isInteraction = true;
20108 app.fgInteractionTime = 0;
20109 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20110 if (app.fgInteractionTime == 0) {
20111 app.fgInteractionTime = nowElapsed;
20112 isInteraction = false;
20114 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20117 isInteraction = app.curProcState
20118 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20119 app.fgInteractionTime = 0;
20121 if (isInteraction && (!app.reportedInteraction
20122 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20123 app.interactionEventTime = nowElapsed;
20124 String[] packages = app.getPackageList();
20125 if (packages != null) {
20126 for (int i = 0; i < packages.length; i++) {
20127 mUsageStatsService.reportEvent(packages[i], app.userId,
20128 UsageEvents.Event.SYSTEM_INTERACTION);
20132 app.reportedInteraction = isInteraction;
20133 if (!isInteraction) {
20134 app.interactionEventTime = 0;
20138 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20139 if (proc.thread != null) {
20140 if (proc.baseProcessTracker != null) {
20141 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20146 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20147 ProcessRecord TOP_APP, boolean doingAll, long now) {
20148 if (app.thread == null) {
20152 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20154 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20157 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20159 if (isForeground != proc.foregroundServices) {
20160 proc.foregroundServices = isForeground;
20161 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20163 if (isForeground) {
20164 if (curProcs == null) {
20165 curProcs = new ArrayList<ProcessRecord>();
20166 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20168 if (!curProcs.contains(proc)) {
20169 curProcs.add(proc);
20170 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20171 proc.info.packageName, proc.info.uid);
20174 if (curProcs != null) {
20175 if (curProcs.remove(proc)) {
20176 mBatteryStatsService.noteEvent(
20177 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20178 proc.info.packageName, proc.info.uid);
20179 if (curProcs.size() <= 0) {
20180 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20186 updateOomAdjLocked();
20191 private final ActivityRecord resumedAppLocked() {
20192 ActivityRecord act = mStackSupervisor.resumedAppLocked();
20196 pkg = act.packageName;
20197 uid = act.info.applicationInfo.uid;
20202 // Has the UID or resumed package name changed?
20203 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20204 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20205 if (mCurResumedPackage != null) {
20206 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20207 mCurResumedPackage, mCurResumedUid);
20209 mCurResumedPackage = pkg;
20210 mCurResumedUid = uid;
20211 if (mCurResumedPackage != null) {
20212 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20213 mCurResumedPackage, mCurResumedUid);
20219 final boolean updateOomAdjLocked(ProcessRecord app) {
20220 final ActivityRecord TOP_ACT = resumedAppLocked();
20221 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20222 final boolean wasCached = app.cached;
20226 // This is the desired cached adjusment we want to tell it to use.
20227 // If our app is currently cached, we know it, and that is it. Otherwise,
20228 // we don't know it yet, and it needs to now be cached we will then
20229 // need to do a complete oom adj.
20230 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20231 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20232 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20233 SystemClock.uptimeMillis());
20234 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20235 // Changed to/from cached state, so apps after it in the LRU
20236 // list may also be changed.
20237 updateOomAdjLocked();
20242 final void updateOomAdjLocked() {
20243 final ActivityRecord TOP_ACT = resumedAppLocked();
20244 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20245 final long now = SystemClock.uptimeMillis();
20246 final long nowElapsed = SystemClock.elapsedRealtime();
20247 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20248 final int N = mLruProcesses.size();
20251 RuntimeException e = new RuntimeException();
20252 e.fillInStackTrace();
20253 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20256 // Reset state in all uid records.
20257 for (int i=mActiveUids.size()-1; i>=0; i--) {
20258 final UidRecord uidRec = mActiveUids.valueAt(i);
20259 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20260 "Starting update of " + uidRec);
20264 mStackSupervisor.rankTaskLayersIfNeeded();
20267 mNewNumServiceProcs = 0;
20268 mNewNumAServiceProcs = 0;
20270 final int emptyProcessLimit;
20271 final int cachedProcessLimit;
20272 if (mProcessLimit <= 0) {
20273 emptyProcessLimit = cachedProcessLimit = 0;
20274 } else if (mProcessLimit == 1) {
20275 emptyProcessLimit = 1;
20276 cachedProcessLimit = 0;
20278 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20279 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20282 // Let's determine how many processes we have running vs.
20283 // how many slots we have for background processes; we may want
20284 // to put multiple processes in a slot of there are enough of
20286 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20287 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20288 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20289 if (numEmptyProcs > cachedProcessLimit) {
20290 // If there are more empty processes than our limit on cached
20291 // processes, then use the cached process limit for the factor.
20292 // This ensures that the really old empty processes get pushed
20293 // down to the bottom, so if we are running low on memory we will
20294 // have a better chance at keeping around more cached processes
20295 // instead of a gazillion empty processes.
20296 numEmptyProcs = cachedProcessLimit;
20298 int emptyFactor = numEmptyProcs/numSlots;
20299 if (emptyFactor < 1) emptyFactor = 1;
20300 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20301 if (cachedFactor < 1) cachedFactor = 1;
20302 int stepCached = 0;
20306 int numTrimming = 0;
20308 mNumNonCachedProcs = 0;
20309 mNumCachedHiddenProcs = 0;
20311 // First update the OOM adjustment for each of the
20312 // application processes based on their current state.
20313 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20314 int nextCachedAdj = curCachedAdj+1;
20315 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20316 int nextEmptyAdj = curEmptyAdj+2;
20317 for (int i=N-1; i>=0; i--) {
20318 ProcessRecord app = mLruProcesses.get(i);
20319 if (!app.killedByAm && app.thread != null) {
20320 app.procStateChanged = false;
20321 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20323 // If we haven't yet assigned the final cached adj
20324 // to the process, do that now.
20325 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20326 switch (app.curProcState) {
20327 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20328 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20329 // This process is a cached process holding activities...
20330 // assign it the next cached value for that type, and then
20331 // step that cached level.
20332 app.curRawAdj = curCachedAdj;
20333 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20334 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20335 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20337 if (curCachedAdj != nextCachedAdj) {
20339 if (stepCached >= cachedFactor) {
20341 curCachedAdj = nextCachedAdj;
20342 nextCachedAdj += 2;
20343 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20344 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20350 // For everything else, assign next empty cached process
20351 // level and bump that up. Note that this means that
20352 // long-running services that have dropped down to the
20353 // cached level will be treated as empty (since their process
20354 // state is still as a service), which is what we want.
20355 app.curRawAdj = curEmptyAdj;
20356 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20357 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20358 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20360 if (curEmptyAdj != nextEmptyAdj) {
20362 if (stepEmpty >= emptyFactor) {
20364 curEmptyAdj = nextEmptyAdj;
20366 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20367 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20375 applyOomAdjLocked(app, true, now, nowElapsed);
20377 // Count the number of process types.
20378 switch (app.curProcState) {
20379 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20380 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20381 mNumCachedHiddenProcs++;
20383 if (numCached > cachedProcessLimit) {
20384 app.kill("cached #" + numCached, true);
20387 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20388 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20389 && app.lastActivityTime < oldTime) {
20390 app.kill("empty for "
20391 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20392 / 1000) + "s", true);
20395 if (numEmpty > emptyProcessLimit) {
20396 app.kill("empty #" + numEmpty, true);
20401 mNumNonCachedProcs++;
20405 if (app.isolated && app.services.size() <= 0) {
20406 // If this is an isolated process, and there are no
20407 // services running in it, then the process is no longer
20408 // needed. We agressively kill these because we can by
20409 // definition not re-use the same process again, and it is
20410 // good to avoid having whatever code was running in them
20411 // left sitting around after no longer needed.
20412 app.kill("isolated not needed", true);
20414 // Keeping this process, update its uid.
20415 final UidRecord uidRec = app.uidRecord;
20416 if (uidRec != null && uidRec.curProcState > app.curProcState) {
20417 uidRec.curProcState = app.curProcState;
20421 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20422 && !app.killedByAm) {
20428 mNumServiceProcs = mNewNumServiceProcs;
20430 // Now determine the memory trimming level of background processes.
20431 // Unfortunately we need to start at the back of the list to do this
20432 // properly. We only do this if the number of background apps we
20433 // are managing to keep around is less than half the maximum we desire;
20434 // if we are keeping a good number around, we'll let them use whatever
20435 // memory they want.
20436 final int numCachedAndEmpty = numCached + numEmpty;
20438 if (numCached <= ProcessList.TRIM_CACHED_APPS
20439 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20440 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20441 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20442 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20443 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20445 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20448 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20450 // We always allow the memory level to go up (better). We only allow it to go
20451 // down if we are in a state where that is allowed, *and* the total number of processes
20452 // has gone down since last time.
20453 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20454 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20455 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20456 if (memFactor > mLastMemoryLevel) {
20457 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20458 memFactor = mLastMemoryLevel;
20459 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20462 if (memFactor != mLastMemoryLevel) {
20463 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
20465 mLastMemoryLevel = memFactor;
20466 mLastNumProcesses = mLruProcesses.size();
20467 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20468 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20469 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20470 if (mLowRamStartTime == 0) {
20471 mLowRamStartTime = now;
20475 switch (memFactor) {
20476 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20477 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20479 case ProcessStats.ADJ_MEM_FACTOR_LOW:
20480 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20483 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20486 int factor = numTrimming/3;
20488 if (mHomeProcess != null) minFactor++;
20489 if (mPreviousProcess != null) minFactor++;
20490 if (factor < minFactor) factor = minFactor;
20491 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20492 for (int i=N-1; i>=0; i--) {
20493 ProcessRecord app = mLruProcesses.get(i);
20494 if (allChanged || app.procStateChanged) {
20495 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20496 app.procStateChanged = false;
20498 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20499 && !app.killedByAm) {
20500 if (app.trimMemoryLevel < curLevel && app.thread != null) {
20502 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20503 "Trimming memory of " + app.processName + " to " + curLevel);
20504 app.thread.scheduleTrimMemory(curLevel);
20505 } catch (RemoteException e) {
20508 // For now we won't do this; our memory trimming seems
20509 // to be good enough at this point that destroying
20510 // activities causes more harm than good.
20511 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20512 && app != mHomeProcess && app != mPreviousProcess) {
20513 // Need to do this on its own message because the stack may not
20514 // be in a consistent state at this point.
20515 // For these apps we will also finish their activities
20516 // to help them free memory.
20517 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20521 app.trimMemoryLevel = curLevel;
20523 if (step >= factor) {
20525 switch (curLevel) {
20526 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20527 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20529 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20530 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20534 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20535 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20536 && app.thread != null) {
20538 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20539 "Trimming memory of heavy-weight " + app.processName
20540 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20541 app.thread.scheduleTrimMemory(
20542 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20543 } catch (RemoteException e) {
20546 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20548 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20549 || app.systemNoUi) && app.pendingUiClean) {
20550 // If this application is now in the background and it
20551 // had done UI, then give it the special trim level to
20552 // have it free UI resources.
20553 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20554 if (app.trimMemoryLevel < level && app.thread != null) {
20556 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20557 "Trimming memory of bg-ui " + app.processName
20559 app.thread.scheduleTrimMemory(level);
20560 } catch (RemoteException e) {
20563 app.pendingUiClean = false;
20565 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20567 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20568 "Trimming memory of fg " + app.processName
20569 + " to " + fgTrimLevel);
20570 app.thread.scheduleTrimMemory(fgTrimLevel);
20571 } catch (RemoteException e) {
20574 app.trimMemoryLevel = fgTrimLevel;
20578 if (mLowRamStartTime != 0) {
20579 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20580 mLowRamStartTime = 0;
20582 for (int i=N-1; i>=0; i--) {
20583 ProcessRecord app = mLruProcesses.get(i);
20584 if (allChanged || app.procStateChanged) {
20585 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20586 app.procStateChanged = false;
20588 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20589 || app.systemNoUi) && app.pendingUiClean) {
20590 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20591 && app.thread != null) {
20593 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20594 "Trimming memory of ui hidden " + app.processName
20595 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20596 app.thread.scheduleTrimMemory(
20597 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20598 } catch (RemoteException e) {
20601 app.pendingUiClean = false;
20603 app.trimMemoryLevel = 0;
20607 if (mAlwaysFinishActivities) {
20608 // Need to do this on its own message because the stack may not
20609 // be in a consistent state at this point.
20610 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20614 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20617 // Update from any uid changes.
20618 for (int i=mActiveUids.size()-1; i>=0; i--) {
20619 final UidRecord uidRec = mActiveUids.valueAt(i);
20620 int uidChange = UidRecord.CHANGE_PROCSTATE;
20621 if (uidRec.setProcState != uidRec.curProcState) {
20622 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20623 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20624 + " to " + uidRec.curProcState);
20625 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20626 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20627 uidRec.lastBackgroundTime = nowElapsed;
20628 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20629 // Note: the background settle time is in elapsed realtime, while
20630 // the handler time base is uptime. All this means is that we may
20631 // stop background uids later than we had intended, but that only
20632 // happens because the device was sleeping so we are okay anyway.
20633 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20638 uidChange = UidRecord.CHANGE_ACTIVE;
20639 uidRec.idle = false;
20641 uidRec.lastBackgroundTime = 0;
20643 uidRec.setProcState = uidRec.curProcState;
20644 enqueueUidChangeLocked(uidRec, -1, uidChange);
20645 noteUidProcessState(uidRec.uid, uidRec.curProcState);
20649 if (mProcessStats.shouldWriteNowLocked(now)) {
20650 mHandler.post(new Runnable() {
20651 @Override public void run() {
20652 synchronized (ActivityManagerService.this) {
20653 mProcessStats.writeStateAsyncLocked();
20659 if (DEBUG_OOM_ADJ) {
20660 final long duration = SystemClock.uptimeMillis() - now;
20662 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20663 new RuntimeException("here").fillInStackTrace());
20665 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20670 final void idleUids() {
20671 synchronized (this) {
20672 final long nowElapsed = SystemClock.elapsedRealtime();
20673 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20675 for (int i=mActiveUids.size()-1; i>=0; i--) {
20676 final UidRecord uidRec = mActiveUids.valueAt(i);
20677 final long bgTime = uidRec.lastBackgroundTime;
20678 if (bgTime > 0 && !uidRec.idle) {
20679 if (bgTime <= maxBgTime) {
20680 uidRec.idle = true;
20681 doStopUidLocked(uidRec.uid, uidRec);
20683 if (nextTime == 0 || nextTime > bgTime) {
20689 if (nextTime > 0) {
20690 mHandler.removeMessages(IDLE_UIDS_MSG);
20691 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20692 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20697 final void runInBackgroundDisabled(int uid) {
20698 synchronized (this) {
20699 UidRecord uidRec = mActiveUids.get(uid);
20700 if (uidRec != null) {
20701 // This uid is actually running... should it be considered background now?
20703 doStopUidLocked(uidRec.uid, uidRec);
20706 // This uid isn't actually running... still send a report about it being "stopped".
20707 doStopUidLocked(uid, null);
20712 final void doStopUidLocked(int uid, final UidRecord uidRec) {
20713 mServices.stopInBackgroundLocked(uid);
20714 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20717 final void trimApplications() {
20718 synchronized (this) {
20721 // First remove any unused application processes whose package
20722 // has been removed.
20723 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20724 final ProcessRecord app = mRemovedProcesses.get(i);
20725 if (app.activities.size() == 0
20726 && app.curReceiver == null && app.services.size() == 0) {
20728 TAG, "Exiting empty application process "
20729 + app.toShortString() + " ("
20730 + (app.thread != null ? app.thread.asBinder() : null)
20732 if (app.pid > 0 && app.pid != MY_PID) {
20733 app.kill("empty", false);
20736 app.thread.scheduleExit();
20737 } catch (Exception e) {
20738 // Ignore exceptions.
20741 cleanUpApplicationRecordLocked(app, false, true, -1);
20742 mRemovedProcesses.remove(i);
20744 if (app.persistent) {
20745 addAppLocked(app.info, false, null /* ABI override */);
20750 // Now update the oom adj for all processes.
20751 updateOomAdjLocked();
20755 /** This method sends the specified signal to each of the persistent apps */
20756 public void signalPersistentProcesses(int sig) throws RemoteException {
20757 if (sig != Process.SIGNAL_USR1) {
20758 throw new SecurityException("Only SIGNAL_USR1 is allowed");
20761 synchronized (this) {
20762 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20763 != PackageManager.PERMISSION_GRANTED) {
20764 throw new SecurityException("Requires permission "
20765 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20768 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20769 ProcessRecord r = mLruProcesses.get(i);
20770 if (r.thread != null && r.persistent) {
20771 Process.sendSignal(r.pid, sig);
20777 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20778 if (proc == null || proc == mProfileProc) {
20779 proc = mProfileProc;
20780 profileType = mProfileType;
20781 clearProfilerLocked();
20783 if (proc == null) {
20787 proc.thread.profilerControl(false, null, profileType);
20788 } catch (RemoteException e) {
20789 throw new IllegalStateException("Process disappeared");
20793 private void clearProfilerLocked() {
20794 if (mProfileFd != null) {
20796 mProfileFd.close();
20797 } catch (IOException e) {
20800 mProfileApp = null;
20801 mProfileProc = null;
20802 mProfileFile = null;
20804 mAutoStopProfiler = false;
20805 mSamplingInterval = 0;
20808 public boolean profileControl(String process, int userId, boolean start,
20809 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20812 synchronized (this) {
20813 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20814 // its own permission.
20815 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20816 != PackageManager.PERMISSION_GRANTED) {
20817 throw new SecurityException("Requires permission "
20818 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20821 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20822 throw new IllegalArgumentException("null profile info or fd");
20825 ProcessRecord proc = null;
20826 if (process != null) {
20827 proc = findProcessLocked(process, userId, "profileControl");
20830 if (start && (proc == null || proc.thread == null)) {
20831 throw new IllegalArgumentException("Unknown process: " + process);
20835 stopProfilerLocked(null, 0);
20836 setProfileApp(proc.info, proc.processName, profilerInfo);
20837 mProfileProc = proc;
20838 mProfileType = profileType;
20839 ParcelFileDescriptor fd = profilerInfo.profileFd;
20842 } catch (IOException e) {
20845 profilerInfo.profileFd = fd;
20846 proc.thread.profilerControl(start, profilerInfo, profileType);
20850 stopProfilerLocked(proc, profileType);
20851 if (profilerInfo != null && profilerInfo.profileFd != null) {
20853 profilerInfo.profileFd.close();
20854 } catch (IOException e) {
20861 } catch (RemoteException e) {
20862 throw new IllegalStateException("Process disappeared");
20864 if (profilerInfo != null && profilerInfo.profileFd != null) {
20866 profilerInfo.profileFd.close();
20867 } catch (IOException e) {
20873 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20874 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20875 userId, true, ALLOW_FULL_ONLY, callName, null);
20876 ProcessRecord proc = null;
20878 int pid = Integer.parseInt(process);
20879 synchronized (mPidsSelfLocked) {
20880 proc = mPidsSelfLocked.get(pid);
20882 } catch (NumberFormatException e) {
20885 if (proc == null) {
20886 ArrayMap<String, SparseArray<ProcessRecord>> all
20887 = mProcessNames.getMap();
20888 SparseArray<ProcessRecord> procs = all.get(process);
20889 if (procs != null && procs.size() > 0) {
20890 proc = procs.valueAt(0);
20891 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20892 for (int i=1; i<procs.size(); i++) {
20893 ProcessRecord thisProc = procs.valueAt(i);
20894 if (thisProc.userId == userId) {
20906 public boolean dumpHeap(String process, int userId, boolean managed,
20907 String path, ParcelFileDescriptor fd) throws RemoteException {
20910 synchronized (this) {
20911 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20912 // its own permission (same as profileControl).
20913 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20914 != PackageManager.PERMISSION_GRANTED) {
20915 throw new SecurityException("Requires permission "
20916 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20920 throw new IllegalArgumentException("null fd");
20923 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20924 if (proc == null || proc.thread == null) {
20925 throw new IllegalArgumentException("Unknown process: " + process);
20928 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20929 if (!isDebuggable) {
20930 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20931 throw new SecurityException("Process not debuggable: " + proc);
20935 proc.thread.dumpHeap(managed, path, fd);
20939 } catch (RemoteException e) {
20940 throw new IllegalStateException("Process disappeared");
20945 } catch (IOException e) {
20952 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20953 String reportPackage) {
20954 if (processName != null) {
20955 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20956 "setDumpHeapDebugLimit()");
20958 synchronized (mPidsSelfLocked) {
20959 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20960 if (proc == null) {
20961 throw new SecurityException("No process found for calling pid "
20962 + Binder.getCallingPid());
20964 if (!Build.IS_DEBUGGABLE
20965 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20966 throw new SecurityException("Not running a debuggable build");
20968 processName = proc.processName;
20970 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20971 throw new SecurityException("Package " + reportPackage + " is not running in "
20976 synchronized (this) {
20977 if (maxMemSize > 0) {
20978 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20981 mMemWatchProcesses.remove(processName, uid);
20983 mMemWatchProcesses.getMap().remove(processName);
20990 public void dumpHeapFinished(String path) {
20991 synchronized (this) {
20992 if (Binder.getCallingPid() != mMemWatchDumpPid) {
20993 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20994 + " does not match last pid " + mMemWatchDumpPid);
20997 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20998 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20999 + " does not match last path " + mMemWatchDumpFile);
21002 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21003 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21007 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21008 public void monitor() {
21009 synchronized (this) { }
21012 void onCoreSettingsChange(Bundle settings) {
21013 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21014 ProcessRecord processRecord = mLruProcesses.get(i);
21016 if (processRecord.thread != null) {
21017 processRecord.thread.setCoreSettings(settings);
21019 } catch (RemoteException re) {
21025 // Multi-user methods
21028 * Start user, if its not already running, but don't bring it to foreground.
21031 public boolean startUserInBackground(final int userId) {
21032 return mUserController.startUser(userId, /* foreground */ false);
21036 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21037 return mUserController.unlockUser(userId, token, secret, listener);
21041 public boolean switchUser(final int targetUserId) {
21042 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21043 UserInfo currentUserInfo;
21044 UserInfo targetUserInfo;
21045 synchronized (this) {
21046 int currentUserId = mUserController.getCurrentUserIdLocked();
21047 currentUserInfo = mUserController.getUserInfo(currentUserId);
21048 targetUserInfo = mUserController.getUserInfo(targetUserId);
21049 if (targetUserInfo == null) {
21050 Slog.w(TAG, "No user info for user #" + targetUserId);
21053 if (!targetUserInfo.supportsSwitchTo()) {
21054 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21057 if (targetUserInfo.isManagedProfile()) {
21058 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21061 mUserController.setTargetUserIdLocked(targetUserId);
21063 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21064 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21065 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21069 void scheduleStartProfilesLocked() {
21070 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21071 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21072 DateUtils.SECOND_IN_MILLIS);
21077 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21078 return mUserController.stopUser(userId, force, callback);
21082 public UserInfo getCurrentUser() {
21083 return mUserController.getCurrentUser();
21087 public boolean isUserRunning(int userId, int flags) {
21088 if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
21089 INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
21090 String msg = "Permission Denial: isUserRunning() from pid="
21091 + Binder.getCallingPid()
21092 + ", uid=" + Binder.getCallingUid()
21093 + " requires " + INTERACT_ACROSS_USERS;
21095 throw new SecurityException(msg);
21097 synchronized (this) {
21098 return mUserController.isUserRunningLocked(userId, flags);
21103 public int[] getRunningUserIds() {
21104 if (checkCallingPermission(INTERACT_ACROSS_USERS)
21105 != PackageManager.PERMISSION_GRANTED) {
21106 String msg = "Permission Denial: isUserRunning() from pid="
21107 + Binder.getCallingPid()
21108 + ", uid=" + Binder.getCallingUid()
21109 + " requires " + INTERACT_ACROSS_USERS;
21111 throw new SecurityException(msg);
21113 synchronized (this) {
21114 return mUserController.getStartedUserArrayLocked();
21119 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
21120 mUserController.registerUserSwitchObserver(observer);
21124 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21125 mUserController.unregisterUserSwitchObserver(observer);
21128 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21129 if (info == null) return null;
21130 ApplicationInfo newInfo = new ApplicationInfo(info);
21131 newInfo.initForUser(userId);
21135 public boolean isUserStopped(int userId) {
21136 synchronized (this) {
21137 return mUserController.getStartedUserStateLocked(userId) == null;
21141 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21143 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21147 ActivityInfo info = new ActivityInfo(aInfo);
21148 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21152 private boolean processSanityChecksLocked(ProcessRecord process) {
21153 if (process == null || process.thread == null) {
21157 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21158 if (!isDebuggable) {
21159 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21167 public boolean startBinderTracking() throws RemoteException {
21168 synchronized (this) {
21169 mBinderTransactionTrackingEnabled = true;
21170 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21171 // permission (same as profileControl).
21172 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21173 != PackageManager.PERMISSION_GRANTED) {
21174 throw new SecurityException("Requires permission "
21175 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21178 for (int i = 0; i < mLruProcesses.size(); i++) {
21179 ProcessRecord process = mLruProcesses.get(i);
21180 if (!processSanityChecksLocked(process)) {
21184 process.thread.startBinderTracking();
21185 } catch (RemoteException e) {
21186 Log.v(TAG, "Process disappared");
21193 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21195 synchronized (this) {
21196 mBinderTransactionTrackingEnabled = false;
21197 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21198 // permission (same as profileControl).
21199 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21200 != PackageManager.PERMISSION_GRANTED) {
21201 throw new SecurityException("Requires permission "
21202 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21206 throw new IllegalArgumentException("null fd");
21209 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21210 pw.println("Binder transaction traces for all processes.\n");
21211 for (ProcessRecord process : mLruProcesses) {
21212 if (!processSanityChecksLocked(process)) {
21216 pw.println("Traces for process: " + process.processName);
21219 TransferPipe tp = new TransferPipe();
21221 process.thread.stopBinderTrackingAndDump(
21222 tp.getWriteFd().getFileDescriptor());
21223 tp.go(fd.getFileDescriptor());
21227 } catch (IOException e) {
21228 pw.println("Failure while dumping IPC traces from " + process +
21229 ". Exception: " + e);
21231 } catch (RemoteException e) {
21232 pw.println("Got a RemoteException while dumping IPC traces from " +
21233 process + ". Exception: " + e);
21244 } catch (IOException e) {
21250 private final class LocalService extends ActivityManagerInternal {
21252 public void onWakefulnessChanged(int wakefulness) {
21253 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21257 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21258 String processName, String abiOverride, int uid, Runnable crashHandler) {
21259 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21260 processName, abiOverride, uid, crashHandler);
21264 public SleepToken acquireSleepToken(String tag) {
21265 Preconditions.checkNotNull(tag);
21267 synchronized (ActivityManagerService.this) {
21268 SleepTokenImpl token = new SleepTokenImpl(tag);
21269 mSleepTokens.add(token);
21270 updateSleepIfNeededLocked();
21271 applyVrModeIfNeededLocked(mFocusedActivity, false);
21277 public ComponentName getHomeActivityForUser(int userId) {
21278 synchronized (ActivityManagerService.this) {
21279 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21280 return homeActivity == null ? null : homeActivity.realActivity;
21285 public void onUserRemoved(int userId) {
21286 synchronized (ActivityManagerService.this) {
21287 ActivityManagerService.this.onUserStoppedLocked(userId);
21292 public void onLocalVoiceInteractionStarted(IBinder activity,
21293 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21294 synchronized (ActivityManagerService.this) {
21295 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21296 voiceSession, voiceInteractor);
21301 public void notifyStartingWindowDrawn() {
21302 synchronized (ActivityManagerService.this) {
21303 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21308 public void notifyAppTransitionStarting(int reason) {
21309 synchronized (ActivityManagerService.this) {
21310 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21315 public void notifyAppTransitionFinished() {
21316 synchronized (ActivityManagerService.this) {
21317 mStackSupervisor.notifyAppTransitionDone();
21322 public void notifyAppTransitionCancelled() {
21323 synchronized (ActivityManagerService.this) {
21324 mStackSupervisor.notifyAppTransitionDone();
21329 public List<IBinder> getTopVisibleActivities() {
21330 synchronized (ActivityManagerService.this) {
21331 return mStackSupervisor.getTopVisibleActivities();
21336 public void notifyDockedStackMinimizedChanged(boolean minimized) {
21337 synchronized (ActivityManagerService.this) {
21338 mStackSupervisor.setDockedStackMinimized(minimized);
21343 public void killForegroundAppsForUser(int userHandle) {
21344 synchronized (ActivityManagerService.this) {
21345 final ArrayList<ProcessRecord> procs = new ArrayList<>();
21346 final int NP = mProcessNames.getMap().size();
21347 for (int ip = 0; ip < NP; ip++) {
21348 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21349 final int NA = apps.size();
21350 for (int ia = 0; ia < NA; ia++) {
21351 final ProcessRecord app = apps.valueAt(ia);
21352 if (app.persistent) {
21353 // We don't kill persistent processes.
21358 } else if (app.userId == userHandle && app.foregroundActivities) {
21359 app.removed = true;
21365 final int N = procs.size();
21366 for (int i = 0; i < N; i++) {
21367 removeProcessLocked(procs.get(i), false, true, "kill all fg");
21373 public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21374 if (!(target instanceof PendingIntentRecord)) {
21375 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21378 ((PendingIntentRecord) target).setWhitelistDuration(duration);
21382 private final class SleepTokenImpl extends SleepToken {
21383 private final String mTag;
21384 private final long mAcquireTime;
21386 public SleepTokenImpl(String tag) {
21388 mAcquireTime = SystemClock.uptimeMillis();
21392 public void release() {
21393 synchronized (ActivityManagerService.this) {
21394 if (mSleepTokens.remove(this)) {
21395 updateSleepIfNeededLocked();
21401 public String toString() {
21402 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21407 * An implementation of IAppTask, that allows an app to manage its own tasks via
21408 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
21409 * only the process that calls getAppTasks() can call the AppTask methods.
21411 class AppTaskImpl extends IAppTask.Stub {
21412 private int mTaskId;
21413 private int mCallingUid;
21415 public AppTaskImpl(int taskId, int callingUid) {
21417 mCallingUid = callingUid;
21420 private void checkCaller() {
21421 if (mCallingUid != Binder.getCallingUid()) {
21422 throw new SecurityException("Caller " + mCallingUid
21423 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21428 public void finishAndRemoveTask() {
21431 synchronized (ActivityManagerService.this) {
21432 long origId = Binder.clearCallingIdentity();
21434 // We remove the task from recents to preserve backwards
21435 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21436 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21439 Binder.restoreCallingIdentity(origId);
21445 public ActivityManager.RecentTaskInfo getTaskInfo() {
21448 synchronized (ActivityManagerService.this) {
21449 long origId = Binder.clearCallingIdentity();
21451 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21453 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21455 return createRecentTaskInfoFromTaskRecord(tr);
21457 Binder.restoreCallingIdentity(origId);
21463 public void moveToFront() {
21465 // Will bring task to front if it already has a root activity.
21466 final long origId = Binder.clearCallingIdentity();
21468 synchronized (this) {
21469 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
21472 Binder.restoreCallingIdentity(origId);
21477 public int startActivity(IBinder whoThread, String callingPackage,
21478 Intent intent, String resolvedType, Bundle bOptions) {
21481 int callingUser = UserHandle.getCallingUserId();
21483 IApplicationThread appThread;
21484 synchronized (ActivityManagerService.this) {
21485 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21487 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21489 appThread = ApplicationThreadNative.asInterface(whoThread);
21490 if (appThread == null) {
21491 throw new IllegalArgumentException("Bad app thread " + appThread);
21494 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21495 resolvedType, null, null, null, null, 0, 0, null, null,
21496 null, bOptions, false, callingUser, null, tr);
21500 public void setExcludeFromRecents(boolean exclude) {
21503 synchronized (ActivityManagerService.this) {
21504 long origId = Binder.clearCallingIdentity();
21506 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21508 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21510 Intent intent = tr.getBaseIntent();
21512 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21514 intent.setFlags(intent.getFlags()
21515 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21518 Binder.restoreCallingIdentity(origId);
21525 * Kill processes for the user with id userId and that depend on the package named packageName
21528 public void killPackageDependents(String packageName, int userId) {
21529 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21530 if (packageName == null) {
21531 throw new NullPointerException(
21532 "Cannot kill the dependents of a package without its name.");
21535 long callingId = Binder.clearCallingIdentity();
21536 IPackageManager pm = AppGlobals.getPackageManager();
21539 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21540 } catch (RemoteException e) {
21542 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21543 throw new IllegalArgumentException(
21544 "Cannot kill dependents of non-existing package " + packageName);
21547 synchronized(this) {
21548 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21549 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21550 "dep: " + packageName);
21553 Binder.restoreCallingIdentity(callingId);