2 * Copyright (C) 2006-2008 The Android Open Source Project
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com.android.server.am;
19 import com.android.internal.telephony.TelephonyIntents;
20 import com.google.android.collect.Lists;
21 import com.google.android.collect.Maps;
22 import com.android.internal.R;
23 import com.android.internal.annotations.GuardedBy;
24 import com.android.internal.app.AssistUtils;
25 import com.android.internal.app.DumpHeapActivity;
26 import com.android.internal.app.IAppOpsCallback;
27 import com.android.internal.app.IAppOpsService;
28 import com.android.internal.app.IVoiceInteractor;
29 import com.android.internal.app.ProcessMap;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.app.procstats.ProcessStats;
32 import com.android.internal.os.BackgroundThread;
33 import com.android.internal.os.BatteryStatsImpl;
34 import com.android.internal.os.IResultReceiver;
35 import com.android.internal.os.ProcessCpuTracker;
36 import com.android.internal.os.TransferPipe;
37 import com.android.internal.os.Zygote;
38 import com.android.internal.os.InstallerConnection.InstallerException;
39 import com.android.internal.util.ArrayUtils;
40 import com.android.internal.util.FastPrintWriter;
41 import com.android.internal.util.FastXmlSerializer;
42 import com.android.internal.util.MemInfoReader;
43 import com.android.internal.util.Preconditions;
44 import com.android.server.AppOpsService;
45 import com.android.server.AttributeCache;
46 import com.android.server.DeviceIdleController;
47 import com.android.server.IntentResolver;
48 import com.android.server.LocalServices;
49 import com.android.server.LockGuard;
50 import com.android.server.ServiceThread;
51 import com.android.server.SystemService;
52 import com.android.server.SystemServiceManager;
53 import com.android.server.Watchdog;
54 import com.android.server.am.ActivityStack.ActivityState;
55 import com.android.server.firewall.IntentFirewall;
56 import com.android.server.pm.Installer;
57 import com.android.server.statusbar.StatusBarManagerInternal;
58 import com.android.server.vr.VrManagerInternal;
59 import com.android.server.wm.WindowManagerService;
61 import org.xmlpull.v1.XmlPullParser;
62 import org.xmlpull.v1.XmlPullParserException;
63 import org.xmlpull.v1.XmlSerializer;
65 import android.Manifest;
66 import android.Manifest.permission;
67 import android.annotation.NonNull;
68 import android.annotation.UserIdInt;
69 import android.app.Activity;
70 import android.app.ActivityManager;
71 import android.app.ActivityManager.RunningTaskInfo;
72 import android.app.ActivityManager.StackId;
73 import android.app.ActivityManager.StackInfo;
74 import android.app.ActivityManager.TaskThumbnailInfo;
75 import android.app.ActivityManagerInternal;
76 import android.app.ActivityManagerInternal.SleepToken;
77 import android.app.ActivityManagerNative;
78 import android.app.ActivityOptions;
79 import android.app.ActivityThread;
80 import android.app.AlertDialog;
81 import android.app.AppGlobals;
82 import android.app.AppOpsManager;
83 import android.app.ApplicationErrorReport;
84 import android.app.ApplicationThreadNative;
85 import android.app.BroadcastOptions;
86 import android.app.Dialog;
87 import android.app.IActivityContainer;
88 import android.app.IActivityContainerCallback;
89 import android.app.IActivityController;
90 import android.app.IAppTask;
91 import android.app.IApplicationThread;
92 import android.app.IInstrumentationWatcher;
93 import android.app.INotificationManager;
94 import android.app.IProcessObserver;
95 import android.app.IServiceConnection;
96 import android.app.IStopUserCallback;
97 import android.app.ITaskStackListener;
98 import android.app.IUiAutomationConnection;
99 import android.app.IUidObserver;
100 import android.app.IUserSwitchObserver;
101 import android.app.Instrumentation;
102 import android.app.Notification;
103 import android.app.NotificationManager;
104 import android.app.PendingIntent;
105 import android.app.ProfilerInfo;
106 import android.app.admin.DevicePolicyManager;
107 import android.app.assist.AssistContent;
108 import android.app.assist.AssistStructure;
109 import android.app.backup.IBackupManager;
110 import android.app.usage.UsageEvents;
111 import android.app.usage.UsageStatsManagerInternal;
112 import android.appwidget.AppWidgetManager;
113 import android.content.ActivityNotFoundException;
114 import android.content.BroadcastReceiver;
115 import android.content.ClipData;
116 import android.content.ComponentCallbacks2;
117 import android.content.ComponentName;
118 import android.content.ContentProvider;
119 import android.content.ContentResolver;
120 import android.content.Context;
121 import android.content.DialogInterface;
122 import android.content.IContentProvider;
123 import android.content.IIntentReceiver;
124 import android.content.IIntentSender;
125 import android.content.Intent;
126 import android.content.IntentFilter;
127 import android.content.IntentSender;
128 import android.content.pm.ActivityInfo;
129 import android.content.pm.ApplicationInfo;
130 import android.content.pm.ConfigurationInfo;
131 import android.content.pm.IPackageDataObserver;
132 import android.content.pm.IPackageManager;
133 import android.content.pm.InstrumentationInfo;
134 import android.content.pm.PackageInfo;
135 import android.content.pm.PackageManager;
136 import android.content.pm.PackageManager.NameNotFoundException;
137 import android.content.pm.PackageManagerInternal;
138 import android.content.pm.ParceledListSlice;
139 import android.content.pm.PathPermission;
140 import android.content.pm.PermissionInfo;
141 import android.content.pm.ProviderInfo;
142 import android.content.pm.ResolveInfo;
143 import android.content.pm.ServiceInfo;
144 import android.content.pm.UserInfo;
145 import android.content.res.CompatibilityInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Bitmap;
150 import android.graphics.Point;
151 import android.graphics.Rect;
152 import android.location.LocationManager;
153 import android.net.Proxy;
154 import android.net.ProxyInfo;
155 import android.net.Uri;
156 import android.os.BatteryStats;
157 import android.os.Binder;
158 import android.os.Build;
159 import android.os.Bundle;
160 import android.os.Debug;
161 import android.os.DropBoxManager;
162 import android.os.Environment;
163 import android.os.FactoryTest;
164 import android.os.FileObserver;
165 import android.os.FileUtils;
166 import android.os.Handler;
167 import android.os.IBinder;
168 import android.os.IPermissionController;
169 import android.os.IProcessInfoService;
170 import android.os.IProgressListener;
171 import android.os.LocaleList;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PersistableBundle;
177 import android.os.PowerManager;
178 import android.os.PowerManagerInternal;
179 import android.os.Process;
180 import android.os.RemoteCallbackList;
181 import android.os.RemoteException;
182 import android.os.ResultReceiver;
183 import android.os.ServiceManager;
184 import android.os.StrictMode;
185 import android.os.SystemClock;
186 import android.os.SystemProperties;
187 import android.os.Trace;
188 import android.os.TransactionTooLargeException;
189 import android.os.UpdateLock;
190 import android.os.UserHandle;
191 import android.os.UserManager;
192 import android.os.WorkSource;
193 import android.provider.Downloads;
194 import android.os.storage.IMountService;
195 import android.os.storage.MountServiceInternal;
196 import android.os.storage.StorageManager;
197 import android.provider.Settings;
198 import android.service.voice.IVoiceInteractionSession;
199 import android.service.voice.VoiceInteractionManagerInternal;
200 import android.service.voice.VoiceInteractionSession;
201 import android.telecom.TelecomManager;
202 import android.text.format.DateUtils;
203 import android.text.format.Time;
204 import android.text.style.SuggestionSpan;
205 import android.util.ArrayMap;
206 import android.util.ArraySet;
207 import android.util.AtomicFile;
208 import android.util.DebugUtils;
209 import android.util.DisplayMetrics;
210 import android.util.EventLog;
211 import android.util.Log;
212 import android.util.Pair;
213 import android.util.PrintWriterPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.TimeUtils;
217 import android.util.Xml;
218 import android.view.Display;
219 import android.view.Gravity;
220 import android.view.LayoutInflater;
221 import android.view.View;
222 import android.view.WindowManager;
225 import java.io.FileDescriptor;
226 import java.io.FileInputStream;
227 import java.io.FileNotFoundException;
228 import java.io.FileOutputStream;
229 import java.io.IOException;
230 import java.io.InputStreamReader;
231 import java.io.PrintWriter;
232 import java.io.StringWriter;
233 import java.lang.ref.WeakReference;
234 import java.nio.charset.StandardCharsets;
235 import java.util.ArrayList;
236 import java.util.Arrays;
237 import java.util.Collections;
238 import java.util.Comparator;
239 import java.util.HashMap;
240 import java.util.HashSet;
241 import java.util.Iterator;
242 import java.util.List;
243 import java.util.Locale;
244 import java.util.Map;
245 import java.util.Objects;
246 import java.util.Set;
247 import java.util.concurrent.atomic.AtomicBoolean;
248 import java.util.concurrent.atomic.AtomicLong;
250 import dalvik.system.VMRuntime;
252 import libcore.io.IoUtils;
253 import libcore.util.EmptyArray;
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270 import static android.content.pm.PackageManager.GET_PROVIDERS;
271 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
273 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
274 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278 import static android.os.Process.PROC_CHAR;
279 import static android.os.Process.PROC_OUT_LONG;
280 import static android.os.Process.PROC_PARENS;
281 import static android.os.Process.PROC_SPACE_TERM;
282 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283 import static android.provider.Settings.Global.DEBUG_APP;
284 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289 import static android.provider.Settings.System.FONT_SCALE;
290 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.readIntAttribute;
292 import static com.android.internal.util.XmlUtils.readLongAttribute;
293 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294 import static com.android.internal.util.XmlUtils.writeIntAttribute;
295 import static com.android.internal.util.XmlUtils.writeLongAttribute;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372 import static org.xmlpull.v1.XmlPullParser.START_TAG;
374 public final class ActivityManagerService extends ActivityManagerNative
375 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
377 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386 private static final String TAG_LRU = TAG + POSTFIX_LRU;
387 private static final String TAG_MU = TAG + POSTFIX_MU;
388 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389 private static final String TAG_POWER = TAG + POSTFIX_POWER;
390 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393 private static final String TAG_PSS = TAG + POSTFIX_PSS;
394 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396 private static final String TAG_STACK = TAG + POSTFIX_STACK;
397 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
403 // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404 // here so that while the job scheduler can depend on AMS, the other way around
405 // need not be the case.
406 public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
408 /** Control over CPU and battery monitoring */
409 // write battery stats every 30 minutes.
410 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411 static final boolean MONITOR_CPU_USAGE = true;
412 // don't sample cpu less than every 5 seconds.
413 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414 // wait possibly forever for next cpu sample.
415 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416 static final boolean MONITOR_THREAD_CPU_USAGE = false;
418 // The flags that are set for all calls we make to the package manager.
419 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
421 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
423 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
425 // Amount of time after a call to stopAppSwitches() during which we will
426 // prevent further untrusted switches from happening.
427 static final long APP_SWITCH_DELAY_TIME = 5*1000;
429 // How long we wait for a launched process to attach to the activity manager
430 // before we decide it's never going to come up for real.
431 static final int PROC_START_TIMEOUT = 10*1000;
432 // How long we wait for an attached process to publish its content providers
433 // before we decide it must be hung.
434 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
436 // How long we will retain processes hosting content providers in the "last activity"
437 // state before allowing them to drop down to the regular cached LRU list. This is
438 // to avoid thrashing of provider processes under low memory situations.
439 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
441 // How long we wait for a launched process to attach to the activity manager
442 // before we decide it's never going to come up for real, when the process was
443 // started with a wrapper for instrumentation (such as Valgrind) because it
444 // could take much longer than usual.
445 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
447 // How long to wait after going idle before forcing apps to GC.
448 static final int GC_TIMEOUT = 5*1000;
450 // The minimum amount of time between successive GC requests for a process.
451 static final int GC_MIN_INTERVAL = 60*1000;
453 // The minimum amount of time between successive PSS requests for a process.
454 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
456 // The minimum amount of time between successive PSS requests for a process
457 // when the request is due to the memory state being lowered.
458 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
460 // The rate at which we check for apps using excessive power -- 15 mins.
461 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
463 // The minimum sample duration we will allow before deciding we have
464 // enough data on wake locks to start killing things.
465 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
467 // The minimum sample duration we will allow before deciding we have
468 // enough data on CPU usage to start killing things.
469 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
471 // How long we allow a receiver to run before giving up on it.
472 static final int BROADCAST_FG_TIMEOUT = 10*1000;
473 static final int BROADCAST_BG_TIMEOUT = 60*1000;
475 // How long we wait until we timeout on key dispatching.
476 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
478 // How long we wait until we timeout on key dispatching during instrumentation.
479 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
481 // This is the amount of time an app needs to be running a foreground service before
482 // we will consider it to be doing interaction for usage stats.
483 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
485 // Maximum amount of time we will allow to elapse before re-reporting usage stats
486 // interaction with foreground processes.
487 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
489 // This is the amount of time we allow an app to settle after it goes into the background,
490 // before we start restricting what it can do.
491 static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
493 // How long to wait in getAssistContextExtras for the activity and foreground services
494 // to respond with the result.
495 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
497 // How long top wait when going through the modern assist (which doesn't need to block
498 // on getting this result before starting to launch its UI).
499 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
501 // Maximum number of persisted Uri grants a package is allowed
502 static final int MAX_PERSISTED_URI_GRANTS = 128;
504 static final int MY_PID = Process.myPid();
506 static final String[] EMPTY_STRING_ARRAY = new String[0];
508 // How many bytes to write into the dropbox log before truncating
509 static final int DROPBOX_MAX_SIZE = 192 * 1024;
510 // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511 // as one line, but close enough for now.
512 static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
514 // Access modes for handleIncomingUser.
515 static final int ALLOW_NON_FULL = 0;
516 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517 static final int ALLOW_FULL_ONLY = 2;
519 // Delay in notifying task stack change listeners (in millis)
520 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
522 // Necessary ApplicationInfo flags to mark an app as persistent
523 private static final int PERSISTENT_MASK =
524 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
526 // Intent sent when remote bugreport collection has been completed
527 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528 "android.intent.action.REMOTE_BUGREPORT_FINISHED";
530 // Delay to disable app launch boost
531 static final int APP_BOOST_MESSAGE_DELAY = 3000;
532 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533 static final int APP_BOOST_TIMEOUT = 2500;
535 // Used to indicate that a task is removed it should also be removed from recents.
536 private static final boolean REMOVE_FROM_RECENTS = true;
537 // Used to indicate that an app transition should be animated.
538 static final boolean ANIMATE = true;
540 // Determines whether to take full screen screenshots
541 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542 public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
544 private static native int nativeMigrateToBoost();
545 private static native int nativeMigrateFromBoost();
546 private boolean mIsBoosted = false;
547 private long mBoostStartTime = 0;
549 /** All system services */
550 SystemServiceManager mSystemServiceManager;
552 private Installer mInstaller;
554 /** Run all ActivityStacks through this */
555 final ActivityStackSupervisor mStackSupervisor;
557 final ActivityStarter mActivityStarter;
559 /** Task stack change listeners. */
560 private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561 new RemoteCallbackList<ITaskStackListener>();
563 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
565 public IntentFirewall mIntentFirewall;
567 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568 // default actuion automatically. Important for devices without direct input
570 private boolean mShowDialogs = true;
571 private boolean mInVrMode = false;
573 // Whether we should use SCHED_FIFO for UI and RenderThreads.
574 private boolean mUseFifoUiScheduling = false;
576 BroadcastQueue mFgBroadcastQueue;
577 BroadcastQueue mBgBroadcastQueue;
578 // Convenient for easy iteration over the queues. Foreground is first
579 // so that dispatch of foreground broadcasts gets precedence.
580 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
582 BroadcastStats mLastBroadcastStats;
583 BroadcastStats mCurBroadcastStats;
585 BroadcastQueue broadcastQueueForIntent(Intent intent) {
586 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588 "Broadcast intent " + intent + " on "
589 + (isFg ? "foreground" : "background") + " queue");
590 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
594 * Activity we have told the window manager to have key focus.
596 ActivityRecord mFocusedActivity = null;
599 * User id of the last activity mFocusedActivity was set to.
601 private int mLastFocusedUserId;
604 * If non-null, we are tracking the time the user spends in the currently focused app.
606 private AppTimeTracker mCurAppTimeTracker;
609 * List of intents that were used to start the most recent tasks.
611 final RecentTasks mRecentTasks;
614 * For addAppTask: cached of the last activity component that was added.
616 ComponentName mLastAddedTaskComponent;
619 * For addAppTask: cached of the last activity uid that was added.
621 int mLastAddedTaskUid;
624 * For addAppTask: cached of the last ActivityInfo that was added.
626 ActivityInfo mLastAddedTaskActivity;
629 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
631 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
634 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
636 String mDeviceOwnerName;
638 final UserController mUserController;
640 final AppErrors mAppErrors;
642 boolean mDoingSetFocusedActivity;
644 public boolean canShowErrorDialogs() {
645 return mShowDialogs && !mSleeping && !mShuttingDown;
648 private static final class PriorityState {
649 // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
650 // the current thread is currently in. When it drops down to zero, we will no longer boost
651 // the thread's priority.
652 private int regionCounter = 0;
654 // The thread's previous priority before boosting.
655 private int prevPriority = Integer.MIN_VALUE;
658 static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
659 @Override protected PriorityState initialValue() {
660 return new PriorityState();
664 static void boostPriorityForLockedSection() {
665 int tid = Process.myTid();
666 int prevPriority = Process.getThreadPriority(tid);
667 PriorityState state = sThreadPriorityState.get();
668 if (state.regionCounter == 0 && prevPriority > -2) {
669 state.prevPriority = prevPriority;
670 Process.setThreadPriority(tid, -2);
672 state.regionCounter++;
675 static void resetPriorityAfterLockedSection() {
676 PriorityState state = sThreadPriorityState.get();
677 state.regionCounter--;
678 if (state.regionCounter == 0 && state.prevPriority > -2) {
679 Process.setThreadPriority(Process.myTid(), state.prevPriority);
683 public class PendingAssistExtras extends Binder implements Runnable {
684 public final ActivityRecord activity;
685 public final Bundle extras;
686 public final Intent intent;
687 public final String hint;
688 public final IResultReceiver receiver;
689 public final int userHandle;
690 public boolean haveResult = false;
691 public Bundle result = null;
692 public AssistStructure structure = null;
693 public AssistContent content = null;
694 public Bundle receiverExtras;
696 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
697 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
698 activity = _activity;
702 receiver = _receiver;
703 receiverExtras = _receiverExtras;
704 userHandle = _userHandle;
708 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
709 synchronized (this) {
713 pendingAssistExtrasTimedOut(this);
717 final ArrayList<PendingAssistExtras> mPendingAssistExtras
718 = new ArrayList<PendingAssistExtras>();
721 * Process management.
723 final ProcessList mProcessList = new ProcessList();
726 * All of the applications we currently have running organized by name.
727 * The keys are strings of the application package name (as
728 * returned by the package manager), and the keys are ApplicationRecord
731 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
734 * Tracking long-term execution of processes to look for abuse and other
737 final ProcessStatsService mProcessStats;
740 * The currently running isolated processes.
742 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
745 * Counter for assigning isolated process uids, to avoid frequently reusing the
748 int mNextIsolatedProcessUid = 0;
751 * The currently running heavy-weight process, if any.
753 ProcessRecord mHeavyWeightProcess = null;
756 * All of the processes we currently have running organized by pid.
757 * The keys are the pid running the application.
759 * <p>NOTE: This object is protected by its own lock, NOT the global
760 * activity manager lock!
762 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
765 * All of the processes that have been forced to be foreground. The key
766 * is the pid of the caller who requested it (we hold a death
769 abstract class ForegroundToken implements IBinder.DeathRecipient {
773 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
776 * List of records for processes that someone had tried to start before the
777 * system was ready. We don't start them at that point, but ensure they
778 * are started by the time booting is complete.
780 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
783 * List of persistent applications that are in the process
786 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
789 * Processes that are being forcibly torn down.
791 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
794 * List of running applications, sorted by recent usage.
795 * The first entry in the list is the least recently used.
797 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
800 * Where in mLruProcesses that the processes hosting activities start.
802 int mLruProcessActivityStart = 0;
805 * Where in mLruProcesses that the processes hosting services start.
806 * This is after (lower index) than mLruProcessesActivityStart.
808 int mLruProcessServiceStart = 0;
811 * List of processes that should gc as soon as things are idle.
813 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
816 * Processes we want to collect PSS data from.
818 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
820 private boolean mBinderTransactionTrackingEnabled = false;
823 * Last time we requested PSS data of all processes.
825 long mLastFullPssTime = SystemClock.uptimeMillis();
828 * If set, the next time we collect PSS data we should do a full collection
829 * with data from native processes and the kernel.
831 boolean mFullPssPending = false;
834 * This is the process holding what we currently consider to be
835 * the "home" activity.
837 ProcessRecord mHomeProcess;
840 * This is the process holding the activity the user last visited that
841 * is in a different process from the one they are currently in.
843 ProcessRecord mPreviousProcess;
846 * The time at which the previous process was last visible.
848 long mPreviousProcessVisibleTime;
851 * Track all uids that have actively running processes.
853 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
856 * This is for verifying the UID report flow.
858 static final boolean VALIDATE_UID_STATES = true;
859 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
862 * Packages that the user has asked to have run in screen size
863 * compatibility mode instead of filling the screen.
865 final CompatModePackages mCompatModePackages;
868 * Set of IntentSenderRecord objects that are currently active.
870 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
871 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
874 * Fingerprints (hashCode()) of stack traces that we've
875 * already logged DropBox entries for. Guarded by itself. If
876 * something (rogue user app) forces this over
877 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
879 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
880 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
883 * Strict Mode background batched logging state.
885 * The string buffer is guarded by itself, and its lock is also
886 * used to determine if another batched write is already
889 private final StringBuilder mStrictModeBuffer = new StringBuilder();
892 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
893 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
895 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
898 * Resolver for broadcast intents to registered receivers.
899 * Holds BroadcastFilter (subclass of IntentFilter).
901 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
902 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
904 protected boolean allowFilterResult(
905 BroadcastFilter filter, List<BroadcastFilter> dest) {
906 IBinder target = filter.receiverList.receiver.asBinder();
907 for (int i = dest.size() - 1; i >= 0; i--) {
908 if (dest.get(i).receiverList.receiver.asBinder() == target) {
916 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
917 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
918 || userId == filter.owningUserId) {
919 return super.newResult(filter, match, userId);
925 protected BroadcastFilter[] newArray(int size) {
926 return new BroadcastFilter[size];
930 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
931 return packageName.equals(filter.packageName);
936 * State of all active sticky broadcasts per user. Keys are the action of the
937 * sticky Intent, values are an ArrayList of all broadcasted intents with
938 * that action (which should usually be one). The SparseArray is keyed
939 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
940 * for stickies that are sent to all users.
942 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
943 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
945 final ActiveServices mServices;
947 final static class Association {
948 final int mSourceUid;
949 final String mSourceProcess;
950 final int mTargetUid;
951 final ComponentName mTargetComponent;
952 final String mTargetProcess;
960 // states of the source process when the bind occurred.
961 int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
962 long mLastStateUptime;
963 long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
964 - ActivityManager.MIN_PROCESS_STATE+1];
966 Association(int sourceUid, String sourceProcess, int targetUid,
967 ComponentName targetComponent, String targetProcess) {
968 mSourceUid = sourceUid;
969 mSourceProcess = sourceProcess;
970 mTargetUid = targetUid;
971 mTargetComponent = targetComponent;
972 mTargetProcess = targetProcess;
977 * When service association tracking is enabled, this is all of the associations we
978 * have seen. Mapping is target uid -> target component -> source uid -> source process name
979 * -> association data.
981 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
982 mAssociations = new SparseArray<>();
983 boolean mTrackingAssociations;
986 * Backup/restore process management
988 String mBackupAppName = null;
989 BackupRecord mBackupTarget = null;
991 final ProviderMap mProviderMap;
994 * List of content providers who have clients waiting for them. The
995 * application is currently being launched and the provider will be
996 * removed from this list once it is published.
998 final ArrayList<ContentProviderRecord> mLaunchingProviders
999 = new ArrayList<ContentProviderRecord>();
1002 * File storing persisted {@link #mGrantedUriPermissions}.
1004 private final AtomicFile mGrantFile;
1006 /** XML constants used in {@link #mGrantFile} */
1007 private static final String TAG_URI_GRANTS = "uri-grants";
1008 private static final String TAG_URI_GRANT = "uri-grant";
1009 private static final String ATTR_USER_HANDLE = "userHandle";
1010 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1011 private static final String ATTR_TARGET_USER_ID = "targetUserId";
1012 private static final String ATTR_SOURCE_PKG = "sourcePkg";
1013 private static final String ATTR_TARGET_PKG = "targetPkg";
1014 private static final String ATTR_URI = "uri";
1015 private static final String ATTR_MODE_FLAGS = "modeFlags";
1016 private static final String ATTR_CREATED_TIME = "createdTime";
1017 private static final String ATTR_PREFIX = "prefix";
1020 * Global set of specific {@link Uri} permissions that have been granted.
1021 * This optimized lookup structure maps from {@link UriPermission#targetUid}
1022 * to {@link UriPermission#uri} to {@link UriPermission}.
1025 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1026 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1028 public static class GrantUri {
1029 public final int sourceUserId;
1030 public final Uri uri;
1031 public boolean prefix;
1033 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1034 this.sourceUserId = sourceUserId;
1036 this.prefix = prefix;
1040 public int hashCode() {
1042 hashCode = 31 * hashCode + sourceUserId;
1043 hashCode = 31 * hashCode + uri.hashCode();
1044 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1049 public boolean equals(Object o) {
1050 if (o instanceof GrantUri) {
1051 GrantUri other = (GrantUri) o;
1052 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1053 && prefix == other.prefix;
1059 public String toString() {
1060 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1061 if (prefix) result += " [prefix]";
1065 public String toSafeString() {
1066 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1067 if (prefix) result += " [prefix]";
1071 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1072 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1073 ContentProvider.getUriWithoutUserId(uri), false);
1077 CoreSettingsObserver mCoreSettingsObserver;
1079 FontScaleSettingObserver mFontScaleSettingObserver;
1081 private final class FontScaleSettingObserver extends ContentObserver {
1082 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1084 public FontScaleSettingObserver() {
1086 ContentResolver resolver = mContext.getContentResolver();
1087 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1091 public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1092 if (mFontScaleUri.equals(uri)) {
1093 updateFontScaleIfNeeded(userId);
1099 * Thread-local storage used to carry caller permissions over through
1100 * indirect content-provider access.
1102 private class Identity {
1103 public final IBinder token;
1104 public final int pid;
1105 public final int uid;
1107 Identity(IBinder _token, int _pid, int _uid) {
1114 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1117 * All information we have collected about the runtime performance of
1118 * any user id that can impact battery performance.
1120 final BatteryStatsService mBatteryStatsService;
1123 * Information about component usage
1125 UsageStatsManagerInternal mUsageStatsService;
1128 * Access to DeviceIdleController service.
1130 DeviceIdleController.LocalService mLocalDeviceIdleController;
1133 * Information about and control over application operations
1135 final AppOpsService mAppOpsService;
1138 * Current configuration information. HistoryRecord objects are given
1139 * a reference to this object to indicate which configuration they are
1140 * currently running in, so this object must be kept immutable.
1142 Configuration mConfiguration = new Configuration();
1145 * Current sequencing integer of the configuration, for skipping old
1148 int mConfigurationSeq = 0;
1150 boolean mSuppressResizeConfigChanges = false;
1153 * Hardware-reported OpenGLES version.
1155 final int GL_ES_VERSION;
1158 * List of initialization arguments to pass to all processes when binding applications to them.
1159 * For example, references to the commonly used services.
1161 HashMap<String, IBinder> mAppBindArgs;
1162 HashMap<String, IBinder> mIsolatedAppBindArgs;
1165 * Temporary to avoid allocations. Protected by main lock.
1167 final StringBuilder mStringBuilder = new StringBuilder(256);
1170 * Used to control how we initialize the service.
1172 ComponentName mTopComponent;
1173 String mTopAction = Intent.ACTION_MAIN;
1176 volatile boolean mProcessesReady = false;
1177 volatile boolean mSystemReady = false;
1178 volatile boolean mOnBattery = false;
1179 volatile int mFactoryTest;
1181 @GuardedBy("this") boolean mBooting = false;
1182 @GuardedBy("this") boolean mCallFinishBooting = false;
1183 @GuardedBy("this") boolean mBootAnimationComplete = false;
1184 @GuardedBy("this") boolean mLaunchWarningShown = false;
1185 @GuardedBy("this") boolean mCheckedForSetup = false;
1190 * The time at which we will allow normal application switches again,
1191 * after a call to {@link #stopAppSwitches()}.
1193 long mAppSwitchesAllowedTime;
1196 * This is set to true after the first switch after mAppSwitchesAllowedTime
1197 * is set; any switches after that will clear the time.
1199 boolean mDidAppSwitch;
1202 * Last time (in realtime) at which we checked for power usage.
1204 long mLastPowerCheckRealtime;
1207 * Last time (in uptime) at which we checked for power usage.
1209 long mLastPowerCheckUptime;
1212 * Set while we are wanting to sleep, to prevent any
1213 * activities from being started/resumed.
1215 private boolean mSleeping = false;
1218 * The process state used for processes that are running the top activities.
1219 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1221 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1224 * Set while we are running a voice interaction. This overrides
1225 * sleeping while it is active.
1227 private IVoiceInteractionSession mRunningVoice;
1230 * For some direct access we need to power manager.
1232 PowerManagerInternal mLocalPowerManager;
1235 * We want to hold a wake lock while running a voice interaction session, since
1236 * this may happen with the screen off and we need to keep the CPU running to
1237 * be able to continue to interact with the user.
1239 PowerManager.WakeLock mVoiceWakeLock;
1242 * State of external calls telling us if the device is awake or asleep.
1244 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1247 * A list of tokens that cause the top activity to be put to sleep.
1248 * They are used by components that may hide and block interaction with underlying
1251 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1253 static final int LOCK_SCREEN_HIDDEN = 0;
1254 static final int LOCK_SCREEN_LEAVING = 1;
1255 static final int LOCK_SCREEN_SHOWN = 2;
1257 * State of external call telling us if the lock screen is shown.
1259 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1262 * Set if we are shutting down the system, similar to sleeping.
1264 boolean mShuttingDown = false;
1267 * Current sequence id for oom_adj computation traversal.
1272 * Current sequence id for process LRU updating.
1277 * Keep track of the non-cached/empty process we last found, to help
1278 * determine how to distribute cached/empty processes next time.
1280 int mNumNonCachedProcs = 0;
1283 * Keep track of the number of cached hidden procs, to balance oom adj
1284 * distribution between those and empty procs.
1286 int mNumCachedHiddenProcs = 0;
1289 * Keep track of the number of service processes we last found, to
1290 * determine on the next iteration which should be B services.
1292 int mNumServiceProcs = 0;
1293 int mNewNumAServiceProcs = 0;
1294 int mNewNumServiceProcs = 0;
1297 * Allow the current computed overall memory level of the system to go down?
1298 * This is set to false when we are killing processes for reasons other than
1299 * memory management, so that the now smaller process list will not be taken as
1300 * an indication that memory is tighter.
1302 boolean mAllowLowerMemLevel = false;
1305 * The last computed memory level, for holding when we are in a state that
1306 * processes are going away for other reasons.
1308 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1311 * The last total number of process we have, to determine if changes actually look
1312 * like a shrinking number of process due to lower RAM.
1314 int mLastNumProcesses;
1317 * The uptime of the last time we performed idle maintenance.
1319 long mLastIdleTime = SystemClock.uptimeMillis();
1322 * Total time spent with RAM that has been added in the past since the last idle time.
1324 long mLowRamTimeSinceLastIdle = 0;
1327 * If RAM is currently low, when that horrible situation started.
1329 long mLowRamStartTime = 0;
1332 * For reporting to battery stats the current top application.
1334 private String mCurResumedPackage = null;
1335 private int mCurResumedUid = -1;
1338 * For reporting to battery stats the apps currently running foreground
1339 * service. The ProcessMap is package/uid tuples; each of these contain
1340 * an array of the currently foreground processes.
1342 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1343 = new ProcessMap<ArrayList<ProcessRecord>>();
1346 * This is set if we had to do a delayed dexopt of an app before launching
1347 * it, to increase the ANR timeouts in that case.
1352 * Set if the systemServer made a call to enterSafeMode.
1357 * If true, we are running under a test environment so will sample PSS from processes
1358 * much more rapidly to try to collect better data when the tests are rapidly
1359 * running through apps.
1361 boolean mTestPssMode = false;
1363 String mDebugApp = null;
1364 boolean mWaitForDebugger = false;
1365 boolean mDebugTransient = false;
1366 String mOrigDebugApp = null;
1367 boolean mOrigWaitForDebugger = false;
1368 boolean mAlwaysFinishActivities = false;
1369 boolean mLenientBackgroundCheck = false;
1370 boolean mForceResizableActivities;
1371 boolean mSupportsMultiWindow;
1372 boolean mSupportsFreeformWindowManagement;
1373 boolean mSupportsPictureInPicture;
1374 boolean mSupportsLeanbackOnly;
1375 Rect mDefaultPinnedStackBounds;
1376 IActivityController mController = null;
1377 boolean mControllerIsAMonkey = false;
1378 String mProfileApp = null;
1379 ProcessRecord mProfileProc = null;
1380 String mProfileFile;
1381 ParcelFileDescriptor mProfileFd;
1382 int mSamplingInterval = 0;
1383 boolean mAutoStopProfiler = false;
1384 int mProfileType = 0;
1385 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1386 String mMemWatchDumpProcName;
1387 String mMemWatchDumpFile;
1388 int mMemWatchDumpPid;
1389 int mMemWatchDumpUid;
1390 String mTrackAllocationApp = null;
1391 String mNativeDebuggingApp = null;
1393 final long[] mTmpLong = new long[2];
1395 static final class ProcessChangeItem {
1396 static final int CHANGE_ACTIVITIES = 1<<0;
1397 static final int CHANGE_PROCESS_STATE = 1<<1;
1402 boolean foregroundActivities;
1405 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1406 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1408 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1409 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1411 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1412 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1414 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1415 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1418 * Runtime CPU use collection thread. This object's lock is used to
1419 * perform synchronization with the thread (notifying it to run).
1421 final Thread mProcessCpuThread;
1424 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1425 * Must acquire this object's lock when accessing it.
1426 * NOTE: this lock will be held while doing long operations (trawling
1427 * through all processes in /proc), so it should never be acquired by
1428 * any critical paths such as when holding the main activity manager lock.
1430 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1431 MONITOR_THREAD_CPU_USAGE);
1432 final AtomicLong mLastCpuTime = new AtomicLong(0);
1433 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1435 long mLastWriteTime = 0;
1438 * Used to retain an update lock when the foreground activity is in
1441 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1444 * Set to true after the system has finished booting.
1446 boolean mBooted = false;
1448 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1449 int mProcessLimitOverride = -1;
1451 WindowManagerService mWindowManager;
1452 final ActivityThread mSystemThread;
1454 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1455 final ProcessRecord mApp;
1457 final IApplicationThread mAppThread;
1459 AppDeathRecipient(ProcessRecord app, int pid,
1460 IApplicationThread thread) {
1461 if (DEBUG_ALL) Slog.v(
1462 TAG, "New death recipient " + this
1463 + " for thread " + thread.asBinder());
1466 mAppThread = thread;
1470 public void binderDied() {
1471 if (DEBUG_ALL) Slog.v(
1472 TAG, "Death received in " + this
1473 + " for thread " + mAppThread.asBinder());
1474 synchronized(ActivityManagerService.this) {
1475 appDiedLocked(mApp, mPid, mAppThread, true);
1480 static final int SHOW_ERROR_UI_MSG = 1;
1481 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1482 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1483 static final int UPDATE_CONFIGURATION_MSG = 4;
1484 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1485 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1486 static final int SERVICE_TIMEOUT_MSG = 12;
1487 static final int UPDATE_TIME_ZONE = 13;
1488 static final int SHOW_UID_ERROR_UI_MSG = 14;
1489 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1490 static final int PROC_START_TIMEOUT_MSG = 20;
1491 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1492 static final int KILL_APPLICATION_MSG = 22;
1493 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1494 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1495 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1496 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1497 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1498 static final int CLEAR_DNS_CACHE_MSG = 28;
1499 static final int UPDATE_HTTP_PROXY_MSG = 29;
1500 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1501 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1502 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1503 static final int REPORT_MEM_USAGE_MSG = 33;
1504 static final int REPORT_USER_SWITCH_MSG = 34;
1505 static final int CONTINUE_USER_SWITCH_MSG = 35;
1506 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1507 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1508 static final int PERSIST_URI_GRANTS_MSG = 38;
1509 static final int REQUEST_ALL_PSS_MSG = 39;
1510 static final int START_PROFILES_MSG = 40;
1511 static final int UPDATE_TIME = 41;
1512 static final int SYSTEM_USER_START_MSG = 42;
1513 static final int SYSTEM_USER_CURRENT_MSG = 43;
1514 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1515 static final int FINISH_BOOTING_MSG = 45;
1516 static final int START_USER_SWITCH_UI_MSG = 46;
1517 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1518 static final int DISMISS_DIALOG_UI_MSG = 48;
1519 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1520 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1521 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1522 static final int DELETE_DUMPHEAP_MSG = 52;
1523 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1524 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1525 static final int REPORT_TIME_TRACKER_MSG = 55;
1526 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1527 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1528 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1529 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1530 static final int IDLE_UIDS_MSG = 60;
1531 static final int SYSTEM_USER_UNLOCK_MSG = 61;
1532 static final int LOG_STACK_STATE = 62;
1533 static final int VR_MODE_CHANGE_MSG = 63;
1534 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1535 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1536 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1537 static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1538 static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1539 static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1540 static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1542 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1543 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1544 static final int FIRST_COMPAT_MODE_MSG = 300;
1545 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1547 static ServiceThread sKillThread = null;
1548 static KillHandler sKillHandler = null;
1550 CompatModeDialog mCompatModeDialog;
1551 UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1552 long mLastMemUsageReportTime = 0;
1555 * Flag whether the current user is a "monkey", i.e. whether
1556 * the UI is driven by a UI automation tool.
1558 private boolean mUserIsMonkey;
1560 /** Flag whether the device has a Recents UI */
1561 boolean mHasRecents;
1563 /** The dimensions of the thumbnails in the Recents UI. */
1564 int mThumbnailWidth;
1565 int mThumbnailHeight;
1566 float mFullscreenThumbnailScale;
1568 final ServiceThread mHandlerThread;
1569 final MainHandler mHandler;
1570 final UiHandler mUiHandler;
1572 PackageManagerInternal mPackageManagerInt;
1574 // VoiceInteraction session ID that changes for each new request except when
1575 // being called for multiwindow assist in a single session.
1576 private int mViSessionId = 1000;
1578 final class KillHandler extends Handler {
1579 static final int KILL_PROCESS_GROUP_MSG = 4000;
1581 public KillHandler(Looper looper) {
1582 super(looper, null, true);
1586 public void handleMessage(Message msg) {
1588 case KILL_PROCESS_GROUP_MSG:
1590 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1591 Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1592 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1597 super.handleMessage(msg);
1602 final class UiHandler extends Handler {
1603 public UiHandler() {
1604 super(com.android.server.UiThread.get().getLooper(), null, true);
1608 public void handleMessage(Message msg) {
1610 case SHOW_ERROR_UI_MSG: {
1611 mAppErrors.handleShowAppErrorUi(msg);
1612 ensureBootCompleted();
1614 case SHOW_NOT_RESPONDING_UI_MSG: {
1615 mAppErrors.handleShowAnrUi(msg);
1616 ensureBootCompleted();
1618 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1619 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1620 synchronized (ActivityManagerService.this) {
1621 ProcessRecord proc = (ProcessRecord) data.get("app");
1623 Slog.e(TAG, "App not found when showing strict mode dialog.");
1626 if (proc.crashDialog != null) {
1627 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1630 AppErrorResult res = (AppErrorResult) data.get("result");
1631 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1632 Dialog d = new StrictModeViolationDialog(mContext,
1633 ActivityManagerService.this, res, proc);
1635 proc.crashDialog = d;
1637 // The device is asleep, so just pretend that the user
1638 // saw a crash dialog and hit "force quit".
1642 ensureBootCompleted();
1644 case SHOW_FACTORY_ERROR_UI_MSG: {
1645 Dialog d = new FactoryErrorDialog(
1646 mContext, msg.getData().getCharSequence("msg"));
1648 ensureBootCompleted();
1650 case WAIT_FOR_DEBUGGER_UI_MSG: {
1651 synchronized (ActivityManagerService.this) {
1652 ProcessRecord app = (ProcessRecord)msg.obj;
1653 if (msg.arg1 != 0) {
1654 if (!app.waitedForDebugger) {
1655 Dialog d = new AppWaitingForDebuggerDialog(
1656 ActivityManagerService.this,
1659 app.waitedForDebugger = true;
1663 if (app.waitDialog != null) {
1664 app.waitDialog.dismiss();
1665 app.waitDialog = null;
1670 case SHOW_UID_ERROR_UI_MSG: {
1672 AlertDialog d = new BaseErrorDialog(mContext);
1673 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1674 d.setCancelable(false);
1675 d.setTitle(mContext.getText(R.string.android_system_label));
1676 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1677 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1678 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1682 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1684 AlertDialog d = new BaseErrorDialog(mContext);
1685 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1686 d.setCancelable(false);
1687 d.setTitle(mContext.getText(R.string.android_system_label));
1688 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1689 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1690 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1694 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1695 synchronized (ActivityManagerService.this) {
1696 ActivityRecord ar = (ActivityRecord) msg.obj;
1697 if (mCompatModeDialog != null) {
1698 if (mCompatModeDialog.mAppInfo.packageName.equals(
1699 ar.info.applicationInfo.packageName)) {
1702 mCompatModeDialog.dismiss();
1703 mCompatModeDialog = null;
1705 if (ar != null && false) {
1706 if (mCompatModePackages.getPackageAskCompatModeLocked(
1708 int mode = mCompatModePackages.computeCompatModeLocked(
1709 ar.info.applicationInfo);
1710 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1711 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1712 mCompatModeDialog = new CompatModeDialog(
1713 ActivityManagerService.this, mContext,
1714 ar.info.applicationInfo);
1715 mCompatModeDialog.show();
1722 case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1723 synchronized (ActivityManagerService.this) {
1724 final ActivityRecord ar = (ActivityRecord) msg.obj;
1725 if (mUnsupportedDisplaySizeDialog != null) {
1726 mUnsupportedDisplaySizeDialog.dismiss();
1727 mUnsupportedDisplaySizeDialog = null;
1729 if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1731 mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1732 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1733 mUnsupportedDisplaySizeDialog.show();
1738 case START_USER_SWITCH_UI_MSG: {
1739 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1742 case DISMISS_DIALOG_UI_MSG: {
1743 final Dialog d = (Dialog) msg.obj;
1747 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1748 dispatchProcessesChanged();
1751 case DISPATCH_PROCESS_DIED_UI_MSG: {
1752 final int pid = msg.arg1;
1753 final int uid = msg.arg2;
1754 dispatchProcessDied(pid, uid);
1757 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1758 dispatchUidsChanged();
1764 final class MainHandler extends Handler {
1765 public MainHandler(Looper looper) {
1766 super(looper, null, true);
1770 public void handleMessage(Message msg) {
1772 case UPDATE_CONFIGURATION_MSG: {
1773 final ContentResolver resolver = mContext.getContentResolver();
1774 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1777 case GC_BACKGROUND_PROCESSES_MSG: {
1778 synchronized (ActivityManagerService.this) {
1779 performAppGcsIfAppropriateLocked();
1782 case SERVICE_TIMEOUT_MSG: {
1785 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1787 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1790 mServices.serviceTimeout((ProcessRecord)msg.obj);
1792 case UPDATE_TIME_ZONE: {
1793 synchronized (ActivityManagerService.this) {
1794 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1795 ProcessRecord r = mLruProcesses.get(i);
1796 if (r.thread != null) {
1798 r.thread.updateTimeZone();
1799 } catch (RemoteException ex) {
1800 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1806 case CLEAR_DNS_CACHE_MSG: {
1807 synchronized (ActivityManagerService.this) {
1808 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1809 ProcessRecord r = mLruProcesses.get(i);
1810 if (r.thread != null) {
1812 r.thread.clearDnsCache();
1813 } catch (RemoteException ex) {
1814 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1820 case UPDATE_HTTP_PROXY_MSG: {
1821 ProxyInfo proxy = (ProxyInfo)msg.obj;
1824 String exclList = "";
1825 Uri pacFileUrl = Uri.EMPTY;
1826 if (proxy != null) {
1827 host = proxy.getHost();
1828 port = Integer.toString(proxy.getPort());
1829 exclList = proxy.getExclusionListAsString();
1830 pacFileUrl = proxy.getPacFileUrl();
1832 synchronized (ActivityManagerService.this) {
1833 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1834 ProcessRecord r = mLruProcesses.get(i);
1835 if (r.thread != null) {
1837 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1838 } catch (RemoteException ex) {
1839 Slog.w(TAG, "Failed to update http proxy for: " +
1840 r.info.processName);
1846 case PROC_START_TIMEOUT_MSG: {
1849 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1851 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1854 ProcessRecord app = (ProcessRecord)msg.obj;
1855 synchronized (ActivityManagerService.this) {
1856 processStartTimedOutLocked(app);
1859 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1860 ProcessRecord app = (ProcessRecord)msg.obj;
1861 synchronized (ActivityManagerService.this) {
1862 processContentProviderPublishTimedOutLocked(app);
1865 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1866 synchronized (ActivityManagerService.this) {
1867 mActivityStarter.doPendingActivityLaunchesLocked(true);
1870 case KILL_APPLICATION_MSG: {
1871 synchronized (ActivityManagerService.this) {
1872 final int appId = msg.arg1;
1873 final int userId = msg.arg2;
1874 Bundle bundle = (Bundle)msg.obj;
1875 String pkg = bundle.getString("pkg");
1876 String reason = bundle.getString("reason");
1877 forceStopPackageLocked(pkg, appId, false, false, true, false,
1878 false, userId, reason);
1881 case FINALIZE_PENDING_INTENT_MSG: {
1882 ((PendingIntentRecord)msg.obj).completeFinalize();
1884 case POST_HEAVY_NOTIFICATION_MSG: {
1885 INotificationManager inm = NotificationManager.getService();
1890 ActivityRecord root = (ActivityRecord)msg.obj;
1891 ProcessRecord process = root.app;
1892 if (process == null) {
1897 Context context = mContext.createPackageContext(process.info.packageName, 0);
1898 String text = mContext.getString(R.string.heavy_weight_notification,
1899 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1900 Notification notification = new Notification.Builder(context)
1901 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1905 .setColor(mContext.getColor(
1906 com.android.internal.R.color.system_notification_accent_color))
1907 .setContentTitle(text)
1909 mContext.getText(R.string.heavy_weight_notification_detail))
1910 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1911 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1912 new UserHandle(root.userId)))
1915 int[] outId = new int[1];
1916 inm.enqueueNotificationWithTag("android", "android", null,
1917 R.string.heavy_weight_notification,
1918 notification, outId, root.userId);
1919 } catch (RuntimeException e) {
1920 Slog.w(ActivityManagerService.TAG,
1921 "Error showing notification for heavy-weight app", e);
1922 } catch (RemoteException e) {
1924 } catch (NameNotFoundException e) {
1925 Slog.w(TAG, "Unable to create context for heavy notification", e);
1928 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1929 INotificationManager inm = NotificationManager.getService();
1934 inm.cancelNotificationWithTag("android", null,
1935 R.string.heavy_weight_notification, msg.arg1);
1936 } catch (RuntimeException e) {
1937 Slog.w(ActivityManagerService.TAG,
1938 "Error canceling notification for service", e);
1939 } catch (RemoteException e) {
1942 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1943 synchronized (ActivityManagerService.this) {
1944 checkExcessivePowerUsageLocked(true);
1945 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1946 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1947 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1950 case REPORT_MEM_USAGE_MSG: {
1951 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1952 Thread thread = new Thread() {
1953 @Override public void run() {
1954 reportMemUsage(memInfos);
1960 case REPORT_USER_SWITCH_MSG: {
1961 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1964 case CONTINUE_USER_SWITCH_MSG: {
1965 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1968 case USER_SWITCH_TIMEOUT_MSG: {
1969 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1972 case IMMERSIVE_MODE_LOCK_MSG: {
1973 final boolean nextState = (msg.arg1 != 0);
1974 if (mUpdateLock.isHeld() != nextState) {
1975 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1976 "Applying new update lock state '" + nextState
1977 + "' for " + (ActivityRecord)msg.obj);
1979 mUpdateLock.acquire();
1981 mUpdateLock.release();
1986 case PERSIST_URI_GRANTS_MSG: {
1987 writeGrantedUriPermissions();
1990 case REQUEST_ALL_PSS_MSG: {
1991 synchronized (ActivityManagerService.this) {
1992 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1996 case START_PROFILES_MSG: {
1997 synchronized (ActivityManagerService.this) {
1998 mUserController.startProfilesLocked();
2003 synchronized (ActivityManagerService.this) {
2004 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2005 ProcessRecord r = mLruProcesses.get(i);
2006 if (r.thread != null) {
2008 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2009 } catch (RemoteException ex) {
2010 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2017 case SYSTEM_USER_START_MSG: {
2018 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2019 Integer.toString(msg.arg1), msg.arg1);
2020 mSystemServiceManager.startUser(msg.arg1);
2023 case SYSTEM_USER_UNLOCK_MSG: {
2024 final int userId = msg.arg1;
2025 mSystemServiceManager.unlockUser(userId);
2026 synchronized (ActivityManagerService.this) {
2027 mRecentTasks.loadUserRecentsLocked(userId);
2029 if (userId == UserHandle.USER_SYSTEM) {
2030 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2032 installEncryptionUnawareProviders(userId);
2033 mUserController.finishUserUnlocked((UserState) msg.obj);
2036 case SYSTEM_USER_CURRENT_MSG: {
2037 mBatteryStatsService.noteEvent(
2038 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2039 Integer.toString(msg.arg2), msg.arg2);
2040 mBatteryStatsService.noteEvent(
2041 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2042 Integer.toString(msg.arg1), msg.arg1);
2043 mSystemServiceManager.switchUser(msg.arg1);
2046 case ENTER_ANIMATION_COMPLETE_MSG: {
2047 synchronized (ActivityManagerService.this) {
2048 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2049 if (r != null && r.app != null && r.app.thread != null) {
2051 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2052 } catch (RemoteException e) {
2058 case FINISH_BOOTING_MSG: {
2059 if (msg.arg1 != 0) {
2060 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2062 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2064 if (msg.arg2 != 0) {
2065 enableScreenAfterBoot();
2069 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2071 Locale l = (Locale) msg.obj;
2072 IBinder service = ServiceManager.getService("mount");
2073 IMountService mountService = IMountService.Stub.asInterface(service);
2074 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2075 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2076 } catch (RemoteException e) {
2077 Log.e(TAG, "Error storing locale for decryption UI", e);
2081 case NOTIFY_TASK_STACK_CHANGE_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).onTaskStackChanged();
2087 } catch (RemoteException e){
2088 // Handled by the RemoteCallbackList
2091 mTaskStackListeners.finishBroadcast();
2095 case NOTIFY_ACTIVITY_PINNED_LISTENERS_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).onActivityPinned();
2101 } catch (RemoteException e){
2102 // Handled by the RemoteCallbackList
2105 mTaskStackListeners.finishBroadcast();
2109 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2110 synchronized (ActivityManagerService.this) {
2111 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2113 // Make a one-way callback to the listener
2114 mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2115 } catch (RemoteException e){
2116 // Handled by the RemoteCallbackList
2119 mTaskStackListeners.finishBroadcast();
2123 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2124 synchronized (ActivityManagerService.this) {
2125 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2127 // Make a one-way callback to the listener
2128 mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2129 } catch (RemoteException e){
2130 // Handled by the RemoteCallbackList
2133 mTaskStackListeners.finishBroadcast();
2137 case NOTIFY_FORCED_RESIZABLE_MSG: {
2138 synchronized (ActivityManagerService.this) {
2139 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2141 // Make a one-way callback to the listener
2142 mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2143 (String) msg.obj, msg.arg1);
2144 } catch (RemoteException e){
2145 // Handled by the RemoteCallbackList
2148 mTaskStackListeners.finishBroadcast();
2152 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2153 synchronized (ActivityManagerService.this) {
2154 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2156 // Make a one-way callback to the listener
2157 mTaskStackListeners.getBroadcastItem(i)
2158 .onActivityDismissingDockedStack();
2159 } catch (RemoteException e){
2160 // Handled by the RemoteCallbackList
2163 mTaskStackListeners.finishBroadcast();
2167 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2168 final int uid = msg.arg1;
2169 final byte[] firstPacket = (byte[]) msg.obj;
2171 synchronized (mPidsSelfLocked) {
2172 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2173 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2176 p.thread.notifyCleartextNetwork(firstPacket);
2177 } catch (RemoteException ignored) {
2184 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2185 final String procName;
2187 final long memLimit;
2188 final String reportPackage;
2189 synchronized (ActivityManagerService.this) {
2190 procName = mMemWatchDumpProcName;
2191 uid = mMemWatchDumpUid;
2192 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2194 val = mMemWatchProcesses.get(procName, 0);
2197 memLimit = val.first;
2198 reportPackage = val.second;
2201 reportPackage = null;
2204 if (procName == null) {
2208 if (DEBUG_PSS) Slog.d(TAG_PSS,
2209 "Showing dump heap notification from " + procName + "/" + uid);
2211 INotificationManager inm = NotificationManager.getService();
2216 String text = mContext.getString(R.string.dump_heap_notification, procName);
2219 Intent deleteIntent = new Intent();
2220 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2221 Intent intent = new Intent();
2222 intent.setClassName("android", DumpHeapActivity.class.getName());
2223 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2224 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2225 if (reportPackage != null) {
2226 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2228 int userId = UserHandle.getUserId(uid);
2229 Notification notification = new Notification.Builder(mContext)
2230 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2233 .setAutoCancel(true)
2235 .setColor(mContext.getColor(
2236 com.android.internal.R.color.system_notification_accent_color))
2237 .setContentTitle(text)
2239 mContext.getText(R.string.dump_heap_notification_detail))
2240 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2241 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2242 new UserHandle(userId)))
2243 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2244 deleteIntent, 0, UserHandle.SYSTEM))
2248 int[] outId = new int[1];
2249 inm.enqueueNotificationWithTag("android", "android", null,
2250 R.string.dump_heap_notification,
2251 notification, outId, userId);
2252 } catch (RuntimeException e) {
2253 Slog.w(ActivityManagerService.TAG,
2254 "Error showing notification for dump heap", e);
2255 } catch (RemoteException e) {
2258 case DELETE_DUMPHEAP_MSG: {
2259 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2260 DumpHeapActivity.JAVA_URI,
2261 Intent.FLAG_GRANT_READ_URI_PERMISSION
2262 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2263 UserHandle.myUserId());
2264 synchronized (ActivityManagerService.this) {
2265 mMemWatchDumpFile = null;
2266 mMemWatchDumpProcName = null;
2267 mMemWatchDumpPid = -1;
2268 mMemWatchDumpUid = -1;
2271 case FOREGROUND_PROFILE_CHANGED_MSG: {
2272 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2274 case REPORT_TIME_TRACKER_MSG: {
2275 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2276 tracker.deliverResult(mContext);
2278 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2279 mUserController.dispatchUserSwitchComplete(msg.arg1);
2281 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2282 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2284 connection.shutdown();
2285 } catch (RemoteException e) {
2286 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2288 // Only a UiAutomation can set this flag and now that
2289 // it is finished we make sure it is reset to its default.
2290 mUserIsMonkey = false;
2292 case APP_BOOST_DEACTIVATE_MSG: {
2293 synchronized(ActivityManagerService.this) {
2295 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2296 nativeMigrateFromBoost();
2298 mBoostStartTime = 0;
2300 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2301 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2306 case IDLE_UIDS_MSG: {
2309 case LOG_STACK_STATE: {
2310 synchronized (ActivityManagerService.this) {
2311 mStackSupervisor.logStackState();
2314 case VR_MODE_CHANGE_MSG: {
2315 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2316 final ActivityRecord r = (ActivityRecord) msg.obj;
2318 ComponentName requestedPackage;
2319 ComponentName callingPackage;
2321 synchronized (ActivityManagerService.this) {
2322 vrMode = r.requestedVrComponent != null;
2323 requestedPackage = r.requestedVrComponent;
2325 callingPackage = r.info.getComponentName();
2326 if (mInVrMode != vrMode) {
2328 mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2329 if (r.app != null) {
2330 ProcessRecord proc = r.app;
2331 if (proc.vrThreadTid > 0) {
2332 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2334 if (mInVrMode == true) {
2335 Process.setThreadScheduler(proc.vrThreadTid,
2336 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2338 Process.setThreadScheduler(proc.vrThreadTid,
2339 Process.SCHED_OTHER, 0);
2341 } catch (IllegalArgumentException e) {
2342 Slog.w(TAG, "Failed to set scheduling policy, thread does"
2343 + " not exist:\n" + e);
2350 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2352 case VR_MODE_APPLY_IF_NEEDED_MSG: {
2353 final ActivityRecord r = (ActivityRecord) msg.obj;
2354 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2356 applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2357 r.info.getComponentName(), false);
2364 static final int COLLECT_PSS_BG_MSG = 1;
2366 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2368 public void handleMessage(Message msg) {
2370 case COLLECT_PSS_BG_MSG: {
2371 long start = SystemClock.uptimeMillis();
2372 MemInfoReader memInfo = null;
2373 synchronized (ActivityManagerService.this) {
2374 if (mFullPssPending) {
2375 mFullPssPending = false;
2376 memInfo = new MemInfoReader();
2379 if (memInfo != null) {
2380 updateCpuStatsNow();
2381 long nativeTotalPss = 0;
2382 synchronized (mProcessCpuTracker) {
2383 final int N = mProcessCpuTracker.countStats();
2384 for (int j=0; j<N; j++) {
2385 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2386 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2387 // This is definitely an application process; skip it.
2390 synchronized (mPidsSelfLocked) {
2391 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2392 // This is one of our own processes; skip it.
2396 nativeTotalPss += Debug.getPss(st.pid, null, null);
2399 memInfo.readMemInfo();
2400 synchronized (ActivityManagerService.this) {
2401 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2402 + (SystemClock.uptimeMillis()-start) + "ms");
2403 final long cachedKb = memInfo.getCachedSizeKb();
2404 final long freeKb = memInfo.getFreeSizeKb();
2405 final long zramKb = memInfo.getZramTotalSizeKb();
2406 final long kernelKb = memInfo.getKernelUsedSizeKb();
2407 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2408 kernelKb*1024, nativeTotalPss*1024);
2409 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2415 long[] tmp = new long[2];
2421 synchronized (ActivityManagerService.this) {
2422 if (mPendingPssProcesses.size() <= 0) {
2423 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2424 "Collected PSS of " + num + " processes in "
2425 + (SystemClock.uptimeMillis() - start) + "ms");
2426 mPendingPssProcesses.clear();
2429 proc = mPendingPssProcesses.remove(0);
2430 procState = proc.pssProcState;
2431 lastPssTime = proc.lastPssTime;
2432 if (proc.thread != null && procState == proc.setProcState
2433 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2434 < SystemClock.uptimeMillis()) {
2442 long pss = Debug.getPss(pid, tmp, null);
2443 synchronized (ActivityManagerService.this) {
2444 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2445 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2447 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2448 SystemClock.uptimeMillis());
2458 public void setSystemProcess() {
2460 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2461 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2462 ServiceManager.addService("meminfo", new MemBinder(this));
2463 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2464 ServiceManager.addService("dbinfo", new DbBinder(this));
2465 if (MONITOR_CPU_USAGE) {
2466 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2468 ServiceManager.addService("permission", new PermissionController(this));
2469 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2471 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2472 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2473 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2475 synchronized (this) {
2476 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2477 app.persistent = true;
2479 app.maxAdj = ProcessList.SYSTEM_ADJ;
2480 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2481 synchronized (mPidsSelfLocked) {
2482 mPidsSelfLocked.put(app.pid, app);
2484 updateLruProcessLocked(app, false, null);
2485 updateOomAdjLocked();
2487 } catch (PackageManager.NameNotFoundException e) {
2488 throw new RuntimeException(
2489 "Unable to find android system package", e);
2493 public void setWindowManager(WindowManagerService wm) {
2494 mWindowManager = wm;
2495 mStackSupervisor.setWindowManager(wm);
2496 mActivityStarter.setWindowManager(wm);
2499 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2500 mUsageStatsService = usageStatsManager;
2503 public void startObservingNativeCrashes() {
2504 final NativeCrashListener ncl = new NativeCrashListener(this);
2508 public IAppOpsService getAppOpsService() {
2509 return mAppOpsService;
2512 static class MemBinder extends Binder {
2513 ActivityManagerService mActivityManagerService;
2514 MemBinder(ActivityManagerService activityManagerService) {
2515 mActivityManagerService = activityManagerService;
2519 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2520 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2521 != PackageManager.PERMISSION_GRANTED) {
2522 pw.println("Permission Denial: can't dump meminfo from from pid="
2523 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2524 + " without permission " + android.Manifest.permission.DUMP);
2528 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2532 static class GraphicsBinder extends Binder {
2533 ActivityManagerService mActivityManagerService;
2534 GraphicsBinder(ActivityManagerService activityManagerService) {
2535 mActivityManagerService = activityManagerService;
2539 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2540 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2541 != PackageManager.PERMISSION_GRANTED) {
2542 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2543 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2544 + " without permission " + android.Manifest.permission.DUMP);
2548 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2552 static class DbBinder extends Binder {
2553 ActivityManagerService mActivityManagerService;
2554 DbBinder(ActivityManagerService activityManagerService) {
2555 mActivityManagerService = activityManagerService;
2559 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2560 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2561 != PackageManager.PERMISSION_GRANTED) {
2562 pw.println("Permission Denial: can't dump dbinfo from from pid="
2563 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2564 + " without permission " + android.Manifest.permission.DUMP);
2568 mActivityManagerService.dumpDbInfo(fd, pw, args);
2572 static class CpuBinder extends Binder {
2573 ActivityManagerService mActivityManagerService;
2574 CpuBinder(ActivityManagerService activityManagerService) {
2575 mActivityManagerService = activityManagerService;
2579 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2580 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2581 != PackageManager.PERMISSION_GRANTED) {
2582 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2583 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2584 + " without permission " + android.Manifest.permission.DUMP);
2588 synchronized (mActivityManagerService.mProcessCpuTracker) {
2589 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2590 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2591 SystemClock.uptimeMillis()));
2596 public static final class Lifecycle extends SystemService {
2597 private final ActivityManagerService mService;
2599 public Lifecycle(Context context) {
2601 mService = new ActivityManagerService(context);
2605 public void onStart() {
2609 public ActivityManagerService getService() {
2614 // Note: This method is invoked on the main thread but may need to attach various
2615 // handlers to other threads. So take care to be explicit about the looper.
2616 public ActivityManagerService(Context systemContext) {
2617 mContext = systemContext;
2618 mFactoryTest = FactoryTest.getMode();
2619 mSystemThread = ActivityThread.currentActivityThread();
2621 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2623 mHandlerThread = new ServiceThread(TAG,
2624 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2625 mHandlerThread.start();
2626 mHandler = new MainHandler(mHandlerThread.getLooper());
2627 mUiHandler = new UiHandler();
2629 /* static; one-time init here */
2630 if (sKillHandler == null) {
2631 sKillThread = new ServiceThread(TAG + ":kill",
2632 android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2633 sKillThread.start();
2634 sKillHandler = new KillHandler(sKillThread.getLooper());
2637 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2638 "foreground", BROADCAST_FG_TIMEOUT, false);
2639 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2640 "background", BROADCAST_BG_TIMEOUT, true);
2641 mBroadcastQueues[0] = mFgBroadcastQueue;
2642 mBroadcastQueues[1] = mBgBroadcastQueue;
2644 mServices = new ActiveServices(this);
2645 mProviderMap = new ProviderMap(this);
2646 mAppErrors = new AppErrors(mContext, this);
2648 // TODO: Move creation of battery stats service outside of activity manager service.
2649 File dataDir = Environment.getDataDirectory();
2650 File systemDir = new File(dataDir, "system");
2652 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2653 mBatteryStatsService.getActiveStatistics().readLocked();
2654 mBatteryStatsService.scheduleWriteToDisk();
2655 mOnBattery = DEBUG_POWER ? true
2656 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2657 mBatteryStatsService.getActiveStatistics().setCallback(this);
2659 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2661 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2662 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2663 new IAppOpsCallback.Stub() {
2664 @Override public void opChanged(int op, int uid, String packageName) {
2665 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2666 if (mAppOpsService.checkOperation(op, uid, packageName)
2667 != AppOpsManager.MODE_ALLOWED) {
2668 runInBackgroundDisabled(uid);
2674 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2676 mUserController = new UserController(this);
2678 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2679 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2681 if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2682 mUseFifoUiScheduling = true;
2685 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2687 mConfiguration.setToDefaults();
2688 mConfiguration.setLocales(LocaleList.getDefault());
2690 mConfigurationSeq = mConfiguration.seq = 1;
2691 mProcessCpuTracker.init();
2693 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2694 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2695 mStackSupervisor = new ActivityStackSupervisor(this);
2696 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2697 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2699 mProcessCpuThread = new Thread("CpuTracker") {
2705 synchronized(this) {
2706 final long now = SystemClock.uptimeMillis();
2707 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2708 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2709 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2710 // + ", write delay=" + nextWriteDelay);
2711 if (nextWriteDelay < nextCpuDelay) {
2712 nextCpuDelay = nextWriteDelay;
2714 if (nextCpuDelay > 0) {
2715 mProcessCpuMutexFree.set(true);
2716 this.wait(nextCpuDelay);
2719 } catch (InterruptedException e) {
2721 updateCpuStatsNow();
2722 } catch (Exception e) {
2723 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2729 Watchdog.getInstance().addMonitor(this);
2730 Watchdog.getInstance().addThread(mHandler);
2733 public void setSystemServiceManager(SystemServiceManager mgr) {
2734 mSystemServiceManager = mgr;
2737 public void setInstaller(Installer installer) {
2738 mInstaller = installer;
2741 private void start() {
2742 Process.removeAllProcessGroups();
2743 mProcessCpuThread.start();
2745 mBatteryStatsService.publish(mContext);
2746 mAppOpsService.publish(mContext);
2747 Slog.d("AppOps", "AppOpsService published");
2748 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2751 void onUserStoppedLocked(int userId) {
2752 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2755 public void initPowerManagement() {
2756 mStackSupervisor.initPowerManagement();
2757 mBatteryStatsService.initPowerManagement();
2758 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2759 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2760 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2761 mVoiceWakeLock.setReferenceCounted(false);
2765 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2766 throws RemoteException {
2767 if (code == SYSPROPS_TRANSACTION) {
2768 // We need to tell all apps about the system property change.
2769 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2770 synchronized(this) {
2771 final int NP = mProcessNames.getMap().size();
2772 for (int ip=0; ip<NP; ip++) {
2773 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2774 final int NA = apps.size();
2775 for (int ia=0; ia<NA; ia++) {
2776 ProcessRecord app = apps.valueAt(ia);
2777 if (app.thread != null) {
2778 procs.add(app.thread.asBinder());
2784 int N = procs.size();
2785 for (int i=0; i<N; i++) {
2786 Parcel data2 = Parcel.obtain();
2788 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2789 } catch (RemoteException e) {
2795 return super.onTransact(code, data, reply, flags);
2796 } catch (RuntimeException e) {
2797 // The activity manager only throws security exceptions, so let's
2799 if (!(e instanceof SecurityException)) {
2800 Slog.wtf(TAG, "Activity Manager Crash", e);
2806 void updateCpuStats() {
2807 final long now = SystemClock.uptimeMillis();
2808 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2811 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2812 synchronized (mProcessCpuThread) {
2813 mProcessCpuThread.notify();
2818 void updateCpuStatsNow() {
2819 synchronized (mProcessCpuTracker) {
2820 mProcessCpuMutexFree.set(false);
2821 final long now = SystemClock.uptimeMillis();
2822 boolean haveNewCpuStats = false;
2824 if (MONITOR_CPU_USAGE &&
2825 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2826 mLastCpuTime.set(now);
2827 mProcessCpuTracker.update();
2828 if (mProcessCpuTracker.hasGoodLastStats()) {
2829 haveNewCpuStats = true;
2830 //Slog.i(TAG, mProcessCpu.printCurrentState());
2831 //Slog.i(TAG, "Total CPU usage: "
2832 // + mProcessCpu.getTotalCpuPercent() + "%");
2834 // Slog the cpu usage if the property is set.
2835 if ("true".equals(SystemProperties.get("events.cpu"))) {
2836 int user = mProcessCpuTracker.getLastUserTime();
2837 int system = mProcessCpuTracker.getLastSystemTime();
2838 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2839 int irq = mProcessCpuTracker.getLastIrqTime();
2840 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2841 int idle = mProcessCpuTracker.getLastIdleTime();
2843 int total = user + system + iowait + irq + softIrq + idle;
2844 if (total == 0) total = 1;
2846 EventLog.writeEvent(EventLogTags.CPU,
2847 ((user+system+iowait+irq+softIrq) * 100) / total,
2848 (user * 100) / total,
2849 (system * 100) / total,
2850 (iowait * 100) / total,
2851 (irq * 100) / total,
2852 (softIrq * 100) / total);
2857 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2858 synchronized(bstats) {
2859 synchronized(mPidsSelfLocked) {
2860 if (haveNewCpuStats) {
2861 if (bstats.startAddingCpuLocked()) {
2864 final int N = mProcessCpuTracker.countStats();
2865 for (int i=0; i<N; i++) {
2866 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2870 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2871 totalUTime += st.rel_utime;
2872 totalSTime += st.rel_stime;
2874 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2875 if (ps == null || !ps.isActive()) {
2876 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2877 pr.info.uid, pr.processName);
2879 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2880 pr.curCpuTime += st.rel_utime + st.rel_stime;
2882 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2883 if (ps == null || !ps.isActive()) {
2884 st.batteryStats = ps = bstats.getProcessStatsLocked(
2885 bstats.mapUid(st.uid), st.name);
2887 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2890 final int userTime = mProcessCpuTracker.getLastUserTime();
2891 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2892 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2893 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2894 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2895 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2896 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2897 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2902 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2903 mLastWriteTime = now;
2904 mBatteryStatsService.scheduleWriteToDisk();
2911 public void batteryNeedsCpuUpdate() {
2912 updateCpuStatsNow();
2916 public void batteryPowerChanged(boolean onBattery) {
2917 // When plugging in, update the CPU stats first before changing
2919 updateCpuStatsNow();
2920 synchronized (this) {
2921 synchronized(mPidsSelfLocked) {
2922 mOnBattery = DEBUG_POWER ? true : onBattery;
2928 public void batterySendBroadcast(Intent intent) {
2929 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2930 AppOpsManager.OP_NONE, null, false, false,
2931 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2935 * Initialize the application bind args. These are passed to each
2936 * process when the bindApplication() IPC is sent to the process. They're
2937 * lazily setup to make sure the services are running when they're asked for.
2939 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2940 // Isolated processes won't get this optimization, so that we don't
2941 // violate the rules about which services they have access to.
2943 if (mIsolatedAppBindArgs == null) {
2944 mIsolatedAppBindArgs = new HashMap<>();
2945 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2947 return mIsolatedAppBindArgs;
2950 if (mAppBindArgs == null) {
2951 mAppBindArgs = new HashMap<>();
2953 // Setup the application init args
2954 mAppBindArgs.put("package", ServiceManager.getService("package"));
2955 mAppBindArgs.put("window", ServiceManager.getService("window"));
2956 mAppBindArgs.put(Context.ALARM_SERVICE,
2957 ServiceManager.getService(Context.ALARM_SERVICE));
2959 return mAppBindArgs;
2962 boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2963 if (r == null || mFocusedActivity == r) {
2967 if (!r.isFocusable()) {
2968 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2972 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2974 final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2975 if (wasDoingSetFocusedActivity) Slog.w(TAG,
2976 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2977 mDoingSetFocusedActivity = true;
2979 final ActivityRecord last = mFocusedActivity;
2980 mFocusedActivity = r;
2981 if (r.task.isApplicationTask()) {
2982 if (mCurAppTimeTracker != r.appTimeTracker) {
2983 // We are switching app tracking. Complete the current one.
2984 if (mCurAppTimeTracker != null) {
2985 mCurAppTimeTracker.stop();
2986 mHandler.obtainMessage(
2987 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2988 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2989 mCurAppTimeTracker = null;
2991 if (r.appTimeTracker != null) {
2992 mCurAppTimeTracker = r.appTimeTracker;
2993 startTimeTrackingFocusedActivityLocked();
2996 startTimeTrackingFocusedActivityLocked();
2999 r.appTimeTracker = null;
3001 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3002 // TODO: Probably not, because we don't want to resume voice on switching
3003 // back to this activity
3004 if (r.task.voiceInteractor != null) {
3005 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3007 finishRunningVoiceLocked();
3008 IVoiceInteractionSession session;
3009 if (last != null && ((session = last.task.voiceSession) != null
3010 || (session = last.voiceSession) != null)) {
3011 // We had been in a voice interaction session, but now focused has
3012 // move to something different. Just finish the session, we can't
3013 // return to it and retain the proper state and synchronization with
3014 // the voice interaction service.
3015 finishVoiceTask(session);
3018 if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3019 mWindowManager.setFocusedApp(r.appToken, true);
3021 applyUpdateLockStateLocked(r);
3022 applyUpdateVrModeLocked(r);
3023 if (mFocusedActivity.userId != mLastFocusedUserId) {
3024 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3025 mHandler.obtainMessage(
3026 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3027 mLastFocusedUserId = mFocusedActivity.userId;
3030 // Log a warning if the focused app is changed during the process. This could
3031 // indicate a problem of the focus setting logic!
3032 if (mFocusedActivity != r) Slog.w(TAG,
3033 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3034 mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3036 EventLogTags.writeAmFocusedActivity(
3037 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3038 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3043 final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3044 if (mFocusedActivity != goingAway) {
3048 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3049 if (focusedStack != null) {
3050 final ActivityRecord top = focusedStack.topActivity();
3051 if (top != null && top.userId != mLastFocusedUserId) {
3052 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3053 mHandler.sendMessage(
3054 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3055 mLastFocusedUserId = top.userId;
3059 // Try to move focus to another activity if possible.
3060 if (setFocusedActivityLocked(
3061 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3065 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3066 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3067 mFocusedActivity = null;
3068 EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3072 public void setFocusedStack(int stackId) {
3073 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3074 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3075 final long callingId = Binder.clearCallingIdentity();
3077 synchronized (this) {
3078 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3079 if (stack == null) {
3082 final ActivityRecord r = stack.topRunningActivityLocked();
3083 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3084 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3088 Binder.restoreCallingIdentity(callingId);
3093 public void setFocusedTask(int taskId) {
3094 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3095 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3096 final long callingId = Binder.clearCallingIdentity();
3098 synchronized (this) {
3099 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3103 if (mUserController.shouldConfirmCredentials(task.userId)) {
3104 mActivityStarter.showConfirmDeviceCredential(task.userId);
3105 if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3106 mStackSupervisor.moveTaskToStackLocked(task.taskId,
3107 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3108 "setFocusedTask", ANIMATE);
3112 final ActivityRecord r = task.topRunningActivityLocked();
3113 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3114 mStackSupervisor.resumeFocusedStackTopActivityLocked();
3118 Binder.restoreCallingIdentity(callingId);
3122 /** Sets the task stack listener that gets callbacks when a task stack changes. */
3124 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3125 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3126 synchronized (this) {
3127 if (listener != null) {
3128 mTaskStackListeners.register(listener);
3134 public void notifyActivityDrawn(IBinder token) {
3135 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3136 synchronized (this) {
3137 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3139 r.task.stack.notifyActivityDrawnLocked(r);
3144 final void applyUpdateLockStateLocked(ActivityRecord r) {
3145 // Modifications to the UpdateLock state are done on our handler, outside
3146 // the activity manager's locks. The new state is determined based on the
3147 // state *now* of the relevant activity record. The object is passed to
3148 // the handler solely for logging detail, not to be consulted/modified.
3149 final boolean nextState = r != null && r.immersive;
3150 mHandler.sendMessage(
3151 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3154 final void applyUpdateVrModeLocked(ActivityRecord r) {
3155 mHandler.sendMessage(
3156 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3159 private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3160 mHandler.sendMessage(
3161 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3164 private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3165 ComponentName callingPackage, boolean immediate) {
3166 VrManagerInternal vrService =
3167 LocalServices.getService(VrManagerInternal.class);
3169 vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3171 vrService.setVrMode(enabled, packageName, userId, callingPackage);
3175 final void showAskCompatModeDialogLocked(ActivityRecord r) {
3176 Message msg = Message.obtain();
3177 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3178 msg.obj = r.task.askedCompatMode ? null : r;
3179 mUiHandler.sendMessage(msg);
3182 final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3183 if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3184 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3185 final Message msg = Message.obtain();
3186 msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3188 mUiHandler.sendMessage(msg);
3192 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3193 String what, Object obj, ProcessRecord srcApp) {
3194 app.lastActivityTime = now;
3196 if (app.activities.size() > 0) {
3197 // Don't want to touch dependent processes that are hosting activities.
3201 int lrui = mLruProcesses.lastIndexOf(app);
3203 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3204 + what + " " + obj + " from " + srcApp);
3208 if (lrui >= index) {
3209 // Don't want to cause this to move dependent processes *back* in the
3210 // list as if they were less frequently used.
3214 if (lrui >= mLruProcessActivityStart) {
3215 // Don't want to touch dependent processes that are hosting activities.
3219 mLruProcesses.remove(lrui);
3223 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3224 + " in LRU list: " + app);
3225 mLruProcesses.add(index, app);
3229 static void killProcessGroup(int uid, int pid) {
3230 if (sKillHandler != null) {
3231 sKillHandler.sendMessage(
3232 sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3234 Slog.w(TAG, "Asked to kill process group before system bringup!");
3235 Process.killProcessGroup(uid, pid);
3239 final void removeLruProcessLocked(ProcessRecord app) {
3240 int lrui = mLruProcesses.lastIndexOf(app);
3243 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3244 Process.killProcessQuiet(app.pid);
3245 killProcessGroup(app.uid, app.pid);
3247 if (lrui <= mLruProcessActivityStart) {
3248 mLruProcessActivityStart--;
3250 if (lrui <= mLruProcessServiceStart) {
3251 mLruProcessServiceStart--;
3253 mLruProcesses.remove(lrui);
3257 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3258 ProcessRecord client) {
3259 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3260 || app.treatLikeActivity;
3261 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3262 if (!activityChange && hasActivity) {
3263 // The process has activities, so we are only allowing activity-based adjustments
3264 // to move it. It should be kept in the front of the list with other
3265 // processes that have activities, and we don't want those to change their
3266 // order except due to activity operations.
3271 final long now = SystemClock.uptimeMillis();
3272 app.lastActivityTime = now;
3274 // First a quick reject: if the app is already at the position we will
3275 // put it, then there is nothing to do.
3277 final int N = mLruProcesses.size();
3278 if (N > 0 && mLruProcesses.get(N-1) == app) {
3279 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3283 if (mLruProcessServiceStart > 0
3284 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3285 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3290 int lrui = mLruProcesses.lastIndexOf(app);
3292 if (app.persistent && lrui >= 0) {
3293 // We don't care about the position of persistent processes, as long as
3294 // they are in the list.
3295 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3299 /* In progress: compute new position first, so we can avoid doing work
3300 if the process is not actually going to move. Not yet working.
3303 boolean inActivity = false, inService = false;
3305 // Process has activities, put it at the very tipsy-top.
3306 addIndex = mLruProcesses.size();
3307 nextIndex = mLruProcessServiceStart;
3309 } else if (hasService) {
3310 // Process has services, put it at the top of the service list.
3311 addIndex = mLruProcessActivityStart;
3312 nextIndex = mLruProcessServiceStart;
3316 // Process not otherwise of interest, it goes to the top of the non-service area.
3317 addIndex = mLruProcessServiceStart;
3318 if (client != null) {
3319 int clientIndex = mLruProcesses.lastIndexOf(client);
3320 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3322 if (clientIndex >= 0 && addIndex > clientIndex) {
3323 addIndex = clientIndex;
3326 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3329 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3330 + mLruProcessActivityStart + "): " + app);
3334 if (lrui < mLruProcessActivityStart) {
3335 mLruProcessActivityStart--;
3337 if (lrui < mLruProcessServiceStart) {
3338 mLruProcessServiceStart--;
3341 if (addIndex > lrui) {
3344 if (nextIndex > lrui) {
3348 mLruProcesses.remove(lrui);
3352 mLruProcesses.add(addIndex, app);
3354 mLruProcessActivityStart++;
3357 mLruProcessActivityStart++;
3363 final int N = mLruProcesses.size();
3364 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3365 // Process doesn't have activities, but has clients with
3366 // activities... move it up, but one below the top (the top
3367 // should always have a real activity).
3368 if (DEBUG_LRU) Slog.d(TAG_LRU,
3369 "Adding to second-top of LRU activity list: " + app);
3370 mLruProcesses.add(N - 1, app);
3371 // To keep it from spamming the LRU list (by making a bunch of clients),
3372 // we will push down any other entries owned by the app.
3373 final int uid = app.info.uid;
3374 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3375 ProcessRecord subProc = mLruProcesses.get(i);
3376 if (subProc.info.uid == uid) {
3377 // We want to push this one down the list. If the process after
3378 // it is for the same uid, however, don't do so, because we don't
3379 // want them internally to be re-ordered.
3380 if (mLruProcesses.get(i - 1).info.uid != uid) {
3381 if (DEBUG_LRU) Slog.d(TAG_LRU,
3382 "Pushing uid " + uid + " swapping at " + i + ": "
3383 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3384 ProcessRecord tmp = mLruProcesses.get(i);
3385 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3386 mLruProcesses.set(i - 1, tmp);
3390 // A gap, we can stop here.
3395 // Process has activities, put it at the very tipsy-top.
3396 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3397 mLruProcesses.add(app);
3399 nextIndex = mLruProcessServiceStart;
3400 } else if (hasService) {
3401 // Process has services, put it at the top of the service list.
3402 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3403 mLruProcesses.add(mLruProcessActivityStart, app);
3404 nextIndex = mLruProcessServiceStart;
3405 mLruProcessActivityStart++;
3407 // Process not otherwise of interest, it goes to the top of the non-service area.
3408 int index = mLruProcessServiceStart;
3409 if (client != null) {
3410 // If there is a client, don't allow the process to be moved up higher
3411 // in the list than that client.
3412 int clientIndex = mLruProcesses.lastIndexOf(client);
3413 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3414 + " when updating " + app);
3415 if (clientIndex <= lrui) {
3416 // Don't allow the client index restriction to push it down farther in the
3417 // list than it already is.
3420 if (clientIndex >= 0 && index > clientIndex) {
3421 index = clientIndex;
3424 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3425 mLruProcesses.add(index, app);
3426 nextIndex = index-1;
3427 mLruProcessActivityStart++;
3428 mLruProcessServiceStart++;
3431 // If the app is currently using a content provider or service,
3432 // bump those processes as well.
3433 for (int j=app.connections.size()-1; j>=0; j--) {
3434 ConnectionRecord cr = app.connections.valueAt(j);
3435 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3436 && cr.binding.service.app != null
3437 && cr.binding.service.app.lruSeq != mLruSeq
3438 && !cr.binding.service.app.persistent) {
3439 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3440 "service connection", cr, app);
3443 for (int j=app.conProviders.size()-1; j>=0; j--) {
3444 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3445 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3446 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3447 "provider reference", cpr, app);
3452 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3453 if (uid == Process.SYSTEM_UID) {
3454 // The system gets to run in any process. If there are multiple
3455 // processes with the same uid, just pick the first (this
3456 // should never happen).
3457 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3458 if (procs == null) return null;
3459 final int procCount = procs.size();
3460 for (int i = 0; i < procCount; i++) {
3461 final int procUid = procs.keyAt(i);
3462 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3463 // Don't use an app process or different user process for system component.
3466 return procs.valueAt(i);
3469 ProcessRecord proc = mProcessNames.get(processName, uid);
3470 if (false && proc != null && !keepIfLarge
3471 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3472 && proc.lastCachedPss >= 4000) {
3473 // Turn this condition on to cause killing to happen regularly, for testing.
3474 if (proc.baseProcessTracker != null) {
3475 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3477 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3478 } else if (proc != null && !keepIfLarge
3479 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3480 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3481 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3482 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3483 if (proc.baseProcessTracker != null) {
3484 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3486 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3492 void notifyPackageUse(String packageName, int reason) {
3493 IPackageManager pm = AppGlobals.getPackageManager();
3495 pm.notifyPackageUse(packageName, reason);
3496 } catch (RemoteException e) {
3500 boolean isNextTransitionForward() {
3501 int transit = mWindowManager.getPendingAppTransition();
3502 return transit == TRANSIT_ACTIVITY_OPEN
3503 || transit == TRANSIT_TASK_OPEN
3504 || transit == TRANSIT_TASK_TO_FRONT;
3507 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3508 String processName, String abiOverride, int uid, Runnable crashHandler) {
3509 synchronized(this) {
3510 ApplicationInfo info = new ApplicationInfo();
3511 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3512 // For isolated processes, the former contains the parent's uid and the latter the
3513 // actual uid of the isolated process.
3514 // In the special case introduced by this method (which is, starting an isolated
3515 // process directly from the SystemServer without an actual parent app process) the
3516 // closest thing to a parent's uid is SYSTEM_UID.
3517 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3518 // the |isolated| logic in the ProcessRecord constructor.
3519 info.uid = Process.SYSTEM_UID;
3520 info.processName = processName;
3521 info.className = entryPoint;
3522 info.packageName = "android";
3523 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3524 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3525 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3526 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3528 return proc != null ? proc.pid : 0;
3532 final ProcessRecord startProcessLocked(String processName,
3533 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3534 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3535 boolean isolated, boolean keepIfLarge) {
3536 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3537 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3538 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3539 null /* crashHandler */);
3542 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3543 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3544 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3545 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3546 long startTime = SystemClock.elapsedRealtime();
3549 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3550 checkTime(startTime, "startProcess: after getProcessRecord");
3552 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3553 // If we are in the background, then check to see if this process
3554 // is bad. If so, we will just silently fail.
3555 if (mAppErrors.isBadProcessLocked(info)) {
3556 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3557 + "/" + info.processName);
3561 // When the user is explicitly starting a process, then clear its
3562 // crash count so that we won't make it bad until they see at
3563 // least one crash dialog again, and make the process good again
3564 // if it had been bad.
3565 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3566 + "/" + info.processName);
3567 mAppErrors.resetProcessCrashTimeLocked(info);
3568 if (mAppErrors.isBadProcessLocked(info)) {
3569 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3570 UserHandle.getUserId(info.uid), info.uid,
3572 mAppErrors.clearBadProcessLocked(info);
3579 // If this is an isolated process, it can't re-use an existing process.
3583 // app launch boost for big.little configurations
3584 // use cpusets to migrate freshly launched tasks to big cores
3585 nativeMigrateToBoost();
3587 mBoostStartTime = SystemClock.uptimeMillis();
3588 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3589 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3591 // We don't have to do anything more if:
3592 // (1) There is an existing application record; and
3593 // (2) The caller doesn't think it is dead, OR there is no thread
3594 // object attached to it so we know it couldn't have crashed; and
3595 // (3) There is a pid assigned to it, so it is either starting or
3597 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3598 + " app=" + app + " knownToBeDead=" + knownToBeDead
3599 + " thread=" + (app != null ? app.thread : null)
3600 + " pid=" + (app != null ? app.pid : -1));
3601 if (app != null && app.pid > 0) {
3602 if ((!knownToBeDead && !app.killed) || app.thread == null) {
3603 // We already have the app running, or are waiting for it to
3604 // come up (we have a pid but not yet its thread), so keep it.
3605 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3606 // If this is a new package in the process, add the package to the list
3607 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3608 checkTime(startTime, "startProcess: done, added package to proc");
3612 // An application record is attached to a previous process,
3614 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3615 checkTime(startTime, "startProcess: bad proc running, killing");
3616 killProcessGroup(app.uid, app.pid);
3617 handleAppDiedLocked(app, true, true);
3618 checkTime(startTime, "startProcess: done killing old proc");
3621 String hostingNameStr = hostingName != null
3622 ? hostingName.flattenToShortString() : null;
3625 checkTime(startTime, "startProcess: creating new process record");
3626 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3628 Slog.w(TAG, "Failed making new process record for "
3629 + processName + "/" + info.uid + " isolated=" + isolated);
3632 app.crashHandler = crashHandler;
3633 checkTime(startTime, "startProcess: done creating new process record");
3635 // If this is a new package in the process, add the package to the list
3636 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3637 checkTime(startTime, "startProcess: added package to existing proc");
3640 // If the system is not ready yet, then hold off on starting this
3641 // process until it is.
3642 if (!mProcessesReady
3643 && !isAllowedWhileBooting(info)
3644 && !allowWhileBooting) {
3645 if (!mProcessesOnHold.contains(app)) {
3646 mProcessesOnHold.add(app);
3648 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3649 "System not ready, putting on hold: " + app);
3650 checkTime(startTime, "startProcess: returning with proc on hold");
3654 checkTime(startTime, "startProcess: stepping in to startProcess");
3656 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3657 checkTime(startTime, "startProcess: done starting proc!");
3658 return (app.pid != 0) ? app : null;
3661 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3662 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3665 private final void startProcessLocked(ProcessRecord app,
3666 String hostingType, String hostingNameStr) {
3667 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3668 null /* entryPoint */, null /* entryPointArgs */);
3671 private final void startProcessLocked(ProcessRecord app, String hostingType,
3672 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3673 long startTime = SystemClock.elapsedRealtime();
3674 if (app.pid > 0 && app.pid != MY_PID) {
3675 checkTime(startTime, "startProcess: removing from pids map");
3676 synchronized (mPidsSelfLocked) {
3677 mPidsSelfLocked.remove(app.pid);
3678 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3680 checkTime(startTime, "startProcess: done removing from pids map");
3684 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3685 "startProcessLocked removing on hold: " + app);
3686 mProcessesOnHold.remove(app);
3688 checkTime(startTime, "startProcess: starting to update cpu stats");
3690 checkTime(startTime, "startProcess: done updating cpu stats");
3694 final int userId = UserHandle.getUserId(app.uid);
3695 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3696 } catch (RemoteException e) {
3697 throw e.rethrowAsRuntimeException();
3702 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3703 if (!app.isolated) {
3704 int[] permGids = null;
3706 checkTime(startTime, "startProcess: getting gids from package manager");
3707 final IPackageManager pm = AppGlobals.getPackageManager();
3708 permGids = pm.getPackageGids(app.info.packageName,
3709 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3710 MountServiceInternal mountServiceInternal = LocalServices.getService(
3711 MountServiceInternal.class);
3712 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3713 app.info.packageName);
3714 } catch (RemoteException e) {
3715 throw e.rethrowAsRuntimeException();
3719 * Add shared application and profile GIDs so applications can share some
3720 * resources like shared libraries and access user-wide resources
3722 if (ArrayUtils.isEmpty(permGids)) {
3725 gids = new int[permGids.length + 2];
3726 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3728 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3729 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3731 checkTime(startTime, "startProcess: building args");
3732 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3733 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3734 && mTopComponent != null
3735 && app.processName.equals(mTopComponent.getPackageName())) {
3738 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3739 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3744 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3745 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3746 // Also turn on CheckJNI for debuggable apps. It's quite
3747 // awkward to turn on otherwise.
3748 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3750 // Run the app in safe mode if its manifest requests so or the
3751 // system is booted in safe mode.
3752 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3753 mSafeMode == true) {
3754 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3756 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3757 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3759 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3760 if ("true".equals(genDebugInfoProperty)) {
3761 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3763 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3764 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3766 if ("1".equals(SystemProperties.get("debug.assert"))) {
3767 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3769 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3770 // Enable all debug flags required by the native debugger.
3771 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3772 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3773 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3774 mNativeDebuggingApp = null;
3777 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3778 if (requiredAbi == null) {
3779 requiredAbi = Build.SUPPORTED_ABIS[0];
3782 String instructionSet = null;
3783 if (app.info.primaryCpuAbi != null) {
3784 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3788 app.requiredAbi = requiredAbi;
3789 app.instructionSet = instructionSet;
3791 // Start the process. It will either succeed and return a result containing
3792 // the PID of the new process, or else throw a RuntimeException.
3793 boolean isActivityProcess = (entryPoint == null);
3794 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3795 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3797 checkTime(startTime, "startProcess: asking zygote to start proc");
3798 Process.ProcessStartResult startResult = Process.start(entryPoint,
3799 app.processName, uid, uid, gids, debugFlags, mountExternal,
3800 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3801 app.info.dataDir, entryPointArgs);
3802 checkTime(startTime, "startProcess: returned from zygote!");
3803 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3805 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3806 checkTime(startTime, "startProcess: done updating battery stats");
3808 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3809 UserHandle.getUserId(uid), startResult.pid, uid,
3810 app.processName, hostingType,
3811 hostingNameStr != null ? hostingNameStr : "");
3814 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3815 app.info.seinfo, app.info.sourceDir, startResult.pid);
3816 } catch (RemoteException ex) {
3820 if (app.persistent) {
3821 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3824 checkTime(startTime, "startProcess: building log message");
3825 StringBuilder buf = mStringBuilder;
3827 buf.append("Start proc ");
3828 buf.append(startResult.pid);
3830 buf.append(app.processName);
3832 UserHandle.formatUid(buf, uid);
3833 if (!isActivityProcess) {
3835 buf.append(entryPoint);
3838 buf.append(" for ");
3839 buf.append(hostingType);
3840 if (hostingNameStr != null) {
3842 buf.append(hostingNameStr);
3844 Slog.i(TAG, buf.toString());
3845 app.setPid(startResult.pid);
3846 app.usingWrapper = startResult.usingWrapper;
3847 app.removed = false;
3849 app.killedByAm = false;
3850 checkTime(startTime, "startProcess: starting to update pids map");
3851 ProcessRecord oldApp;
3852 synchronized (mPidsSelfLocked) {
3853 oldApp = mPidsSelfLocked.get(startResult.pid);
3855 // If there is already an app occupying that pid that hasn't been cleaned up
3856 if (oldApp != null && !app.isolated) {
3857 // Clean up anything relating to this pid first
3858 Slog.w(TAG, "Reusing pid " + startResult.pid
3859 + " while app is still mapped to it");
3860 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3861 true /*replacingPid*/);
3863 synchronized (mPidsSelfLocked) {
3864 this.mPidsSelfLocked.put(startResult.pid, app);
3865 if (isActivityProcess) {
3866 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3868 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3869 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3872 checkTime(startTime, "startProcess: done updating pids map");
3873 } catch (RuntimeException e) {
3874 Slog.e(TAG, "Failure starting process " + app.processName, e);
3876 // Something went very wrong while trying to start this process; one
3877 // common case is when the package is frozen due to an active
3878 // upgrade. To recover, clean up any active bookkeeping related to
3879 // starting this process. (We already invoked this method once when
3880 // the package was initially frozen through KILL_APPLICATION_MSG, so
3881 // it doesn't hurt to use it again.)
3882 forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3883 false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3887 void updateUsageStats(ActivityRecord component, boolean resumed) {
3888 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3889 "updateUsageStats: comp=" + component + "res=" + resumed);
3890 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3892 if (mUsageStatsService != null) {
3893 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3894 UsageEvents.Event.MOVE_TO_FOREGROUND);
3896 synchronized (stats) {
3897 stats.noteActivityResumedLocked(component.app.uid);
3900 if (mUsageStatsService != null) {
3901 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902 UsageEvents.Event.MOVE_TO_BACKGROUND);
3904 synchronized (stats) {
3905 stats.noteActivityPausedLocked(component.app.uid);
3910 Intent getHomeIntent() {
3911 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3912 intent.setComponent(mTopComponent);
3913 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3914 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3915 intent.addCategory(Intent.CATEGORY_HOME);
3920 boolean startHomeActivityLocked(int userId, String reason) {
3921 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3922 && mTopAction == null) {
3923 // We are running in factory test mode, but unable to find
3924 // the factory test app, so just sit around displaying the
3925 // error message and don't try to start anything.
3928 Intent intent = getHomeIntent();
3929 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3930 if (aInfo != null) {
3931 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3932 // Don't do this if the home app is currently being
3934 aInfo = new ActivityInfo(aInfo);
3935 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3936 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3937 aInfo.applicationInfo.uid, true);
3938 if (app == null || app.instrumentationClass == null) {
3939 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3940 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3943 Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3949 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3950 ActivityInfo ai = null;
3951 ComponentName comp = intent.getComponent();
3955 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3957 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3959 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3963 ai = info.activityInfo;
3966 } catch (RemoteException e) {
3974 * Starts the "new version setup screen" if appropriate.
3976 void startSetupActivityLocked() {
3977 // Only do this once per boot.
3978 if (mCheckedForSetup) {
3982 // We will show this screen if the current one is a different
3983 // version than the last one shown, and we are not running in
3984 // low-level factory test mode.
3985 final ContentResolver resolver = mContext.getContentResolver();
3986 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3987 Settings.Global.getInt(resolver,
3988 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3989 mCheckedForSetup = true;
3991 // See if we should be showing the platform update setup UI.
3992 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3993 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3994 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3995 if (!ris.isEmpty()) {
3996 final ResolveInfo ri = ris.get(0);
3997 String vers = ri.activityInfo.metaData != null
3998 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4000 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4001 vers = ri.activityInfo.applicationInfo.metaData.getString(
4002 Intent.METADATA_SETUP_VERSION);
4004 String lastVers = Settings.Secure.getString(
4005 resolver, Settings.Secure.LAST_SETUP_SHOWN);
4006 if (vers != null && !vers.equals(lastVers)) {
4007 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4008 intent.setComponent(new ComponentName(
4009 ri.activityInfo.packageName, ri.activityInfo.name));
4010 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4011 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4012 null, 0, 0, 0, null, false, false, null, null, null);
4018 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4019 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4022 void enforceNotIsolatedCaller(String caller) {
4023 if (UserHandle.isIsolated(Binder.getCallingUid())) {
4024 throw new SecurityException("Isolated process not allowed to call " + caller);
4028 void enforceShellRestriction(String restriction, int userHandle) {
4029 if (Binder.getCallingUid() == Process.SHELL_UID) {
4030 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4031 throw new SecurityException("Shell does not have permission to access user "
4038 public int getFrontActivityScreenCompatMode() {
4039 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4040 synchronized (this) {
4041 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4046 public void setFrontActivityScreenCompatMode(int mode) {
4047 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4048 "setFrontActivityScreenCompatMode");
4049 synchronized (this) {
4050 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4055 public int getPackageScreenCompatMode(String packageName) {
4056 enforceNotIsolatedCaller("getPackageScreenCompatMode");
4057 synchronized (this) {
4058 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4063 public void setPackageScreenCompatMode(String packageName, int mode) {
4064 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4065 "setPackageScreenCompatMode");
4066 synchronized (this) {
4067 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4072 public boolean getPackageAskScreenCompat(String packageName) {
4073 enforceNotIsolatedCaller("getPackageAskScreenCompat");
4074 synchronized (this) {
4075 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4080 public void setPackageAskScreenCompat(String packageName, boolean ask) {
4081 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4082 "setPackageAskScreenCompat");
4083 synchronized (this) {
4084 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4088 private boolean hasUsageStatsPermission(String callingPackage) {
4089 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4090 Binder.getCallingUid(), callingPackage);
4091 if (mode == AppOpsManager.MODE_DEFAULT) {
4092 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4093 == PackageManager.PERMISSION_GRANTED;
4095 return mode == AppOpsManager.MODE_ALLOWED;
4099 public int getPackageProcessState(String packageName, String callingPackage) {
4100 if (!hasUsageStatsPermission(callingPackage)) {
4101 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4102 "getPackageProcessState");
4105 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4106 synchronized (this) {
4107 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4108 final ProcessRecord proc = mLruProcesses.get(i);
4109 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4110 || procState > proc.setProcState) {
4111 boolean found = false;
4112 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4113 if (proc.pkgList.keyAt(j).equals(packageName)) {
4114 procState = proc.setProcState;
4118 if (proc.pkgDeps != null && !found) {
4119 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4120 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4121 procState = proc.setProcState;
4133 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4134 synchronized (this) {
4135 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4139 if (app.trimMemoryLevel < level && app.thread != null &&
4140 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4141 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4143 app.thread.scheduleTrimMemory(level);
4144 app.trimMemoryLevel = level;
4146 } catch (RemoteException e) {
4147 // Fallthrough to failure case.
4154 private void dispatchProcessesChanged() {
4156 synchronized (this) {
4157 N = mPendingProcessChanges.size();
4158 if (mActiveProcessChanges.length < N) {
4159 mActiveProcessChanges = new ProcessChangeItem[N];
4161 mPendingProcessChanges.toArray(mActiveProcessChanges);
4162 mPendingProcessChanges.clear();
4163 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4164 "*** Delivering " + N + " process changes");
4167 int i = mProcessObservers.beginBroadcast();
4170 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4171 if (observer != null) {
4173 for (int j=0; j<N; j++) {
4174 ProcessChangeItem item = mActiveProcessChanges[j];
4175 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4176 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4177 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4178 + item.uid + ": " + item.foregroundActivities);
4179 observer.onForegroundActivitiesChanged(item.pid, item.uid,
4180 item.foregroundActivities);
4182 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4183 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4184 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4185 + ": " + item.processState);
4186 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4189 } catch (RemoteException e) {
4193 mProcessObservers.finishBroadcast();
4195 synchronized (this) {
4196 for (int j=0; j<N; j++) {
4197 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4202 private void dispatchProcessDied(int pid, int uid) {
4203 int i = mProcessObservers.beginBroadcast();
4206 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4207 if (observer != null) {
4209 observer.onProcessDied(pid, uid);
4210 } catch (RemoteException e) {
4214 mProcessObservers.finishBroadcast();
4217 private void dispatchUidsChanged() {
4219 synchronized (this) {
4220 N = mPendingUidChanges.size();
4221 if (mActiveUidChanges.length < N) {
4222 mActiveUidChanges = new UidRecord.ChangeItem[N];
4224 for (int i=0; i<N; i++) {
4225 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4226 mActiveUidChanges[i] = change;
4227 if (change.uidRecord != null) {
4228 change.uidRecord.pendingChange = null;
4229 change.uidRecord = null;
4232 mPendingUidChanges.clear();
4233 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4234 "*** Delivering " + N + " uid changes");
4237 if (mLocalPowerManager != null) {
4238 for (int j=0; j<N; j++) {
4239 UidRecord.ChangeItem item = mActiveUidChanges[j];
4240 if (item.change == UidRecord.CHANGE_GONE
4241 || item.change == UidRecord.CHANGE_GONE_IDLE) {
4242 mLocalPowerManager.uidGone(item.uid);
4244 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4249 int i = mUidObservers.beginBroadcast();
4252 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4253 final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4254 if (observer != null) {
4256 for (int j=0; j<N; j++) {
4257 UidRecord.ChangeItem item = mActiveUidChanges[j];
4258 final int change = item.change;
4259 UidRecord validateUid = null;
4260 if (VALIDATE_UID_STATES && i == 0) {
4261 validateUid = mValidateUids.get(item.uid);
4262 if (validateUid == null && change != UidRecord.CHANGE_GONE
4263 && change != UidRecord.CHANGE_GONE_IDLE) {
4264 validateUid = new UidRecord(item.uid);
4265 mValidateUids.put(item.uid, validateUid);
4268 if (change == UidRecord.CHANGE_IDLE
4269 || change == UidRecord.CHANGE_GONE_IDLE) {
4270 if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4271 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4272 "UID idle uid=" + item.uid);
4273 observer.onUidIdle(item.uid);
4275 if (VALIDATE_UID_STATES && i == 0) {
4276 if (validateUid != null) {
4277 validateUid.idle = true;
4280 } else if (change == UidRecord.CHANGE_ACTIVE) {
4281 if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4282 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4283 "UID active uid=" + item.uid);
4284 observer.onUidActive(item.uid);
4286 if (VALIDATE_UID_STATES && i == 0) {
4287 validateUid.idle = false;
4290 if (change == UidRecord.CHANGE_GONE
4291 || change == UidRecord.CHANGE_GONE_IDLE) {
4292 if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4293 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4294 "UID gone uid=" + item.uid);
4295 observer.onUidGone(item.uid);
4297 if (VALIDATE_UID_STATES && i == 0) {
4298 if (validateUid != null) {
4299 mValidateUids.remove(item.uid);
4303 if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4304 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4305 "UID CHANGED uid=" + item.uid
4306 + ": " + item.processState);
4307 observer.onUidStateChanged(item.uid, item.processState);
4309 if (VALIDATE_UID_STATES && i == 0) {
4310 validateUid.curProcState = validateUid.setProcState
4311 = item.processState;
4315 } catch (RemoteException e) {
4319 mUidObservers.finishBroadcast();
4321 synchronized (this) {
4322 for (int j=0; j<N; j++) {
4323 mAvailUidChanges.add(mActiveUidChanges[j]);
4329 public final int startActivity(IApplicationThread caller, String callingPackage,
4330 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4331 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4332 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4333 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4334 UserHandle.getCallingUserId());
4337 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4338 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4339 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4340 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4341 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4343 // TODO: Switch to user app stacks here.
4344 String mimeType = intent.getType();
4345 final Uri data = intent.getData();
4346 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4347 mimeType = getProviderMimeType(data, userId);
4349 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4351 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4352 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4353 null, 0, 0, null, null, null, null, false, userId, container, null);
4357 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4358 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4359 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4360 enforceNotIsolatedCaller("startActivity");
4361 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4362 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4363 // TODO: Switch to user app stacks here.
4364 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4365 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4366 profilerInfo, null, null, bOptions, false, userId, null, null);
4370 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4371 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4372 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4375 // This is very dangerous -- it allows you to perform a start activity (including
4376 // permission grants) as any app that may launch one of your own activities. So
4377 // we will only allow this to be done from activities that are part of the core framework,
4378 // and then only when they are running as the system.
4379 final ActivityRecord sourceRecord;
4380 final int targetUid;
4381 final String targetPackage;
4382 synchronized (this) {
4383 if (resultTo == null) {
4384 throw new SecurityException("Must be called from an activity");
4386 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4387 if (sourceRecord == null) {
4388 throw new SecurityException("Called with bad activity token: " + resultTo);
4390 if (!sourceRecord.info.packageName.equals("android")) {
4391 throw new SecurityException(
4392 "Must be called from an activity that is declared in the android package");
4394 if (sourceRecord.app == null) {
4395 throw new SecurityException("Called without a process attached to activity");
4397 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4398 // This is still okay, as long as this activity is running under the
4399 // uid of the original calling activity.
4400 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4401 throw new SecurityException(
4402 "Calling activity in uid " + sourceRecord.app.uid
4403 + " must be system uid or original calling uid "
4404 + sourceRecord.launchedFromUid);
4407 if (ignoreTargetSecurity) {
4408 if (intent.getComponent() == null) {
4409 throw new SecurityException(
4410 "Component must be specified with ignoreTargetSecurity");
4412 if (intent.getSelector() != null) {
4413 throw new SecurityException(
4414 "Selector not allowed with ignoreTargetSecurity");
4417 targetUid = sourceRecord.launchedFromUid;
4418 targetPackage = sourceRecord.launchedFromPackage;
4421 if (userId == UserHandle.USER_NULL) {
4422 userId = UserHandle.getUserId(sourceRecord.app.uid);
4425 // TODO: Switch to user app stacks here.
4427 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4428 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4429 null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4431 } catch (SecurityException e) {
4432 // XXX need to figure out how to propagate to original app.
4433 // A SecurityException here is generally actually a fault of the original
4434 // calling activity (such as a fairly granting permissions), so propagate it
4437 StringBuilder msg = new StringBuilder();
4438 msg.append("While launching");
4439 msg.append(intent.toString());
4441 msg.append(e.getMessage());
4448 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4449 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4450 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4451 enforceNotIsolatedCaller("startActivityAndWait");
4452 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4453 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4454 WaitResult res = new WaitResult();
4455 // TODO: Switch to user app stacks here.
4456 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4457 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4458 bOptions, false, userId, null, null);
4463 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4464 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4465 int startFlags, Configuration config, Bundle bOptions, int userId) {
4466 enforceNotIsolatedCaller("startActivityWithConfig");
4467 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4468 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4469 // TODO: Switch to user app stacks here.
4470 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4471 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4472 null, null, config, bOptions, false, userId, null, null);
4477 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4478 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4479 int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4480 throws TransactionTooLargeException {
4481 enforceNotIsolatedCaller("startActivityIntentSender");
4482 // Refuse possible leaked file descriptors
4483 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4484 throw new IllegalArgumentException("File descriptors passed in Intent");
4487 IIntentSender sender = intent.getTarget();
4488 if (!(sender instanceof PendingIntentRecord)) {
4489 throw new IllegalArgumentException("Bad PendingIntent object");
4492 PendingIntentRecord pir = (PendingIntentRecord)sender;
4494 synchronized (this) {
4495 // If this is coming from the currently resumed activity, it is
4496 // effectively saying that app switches are allowed at this point.
4497 final ActivityStack stack = getFocusedStack();
4498 if (stack.mResumedActivity != null &&
4499 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4500 mAppSwitchesAllowedTime = 0;
4503 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4504 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4509 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4510 Intent intent, String resolvedType, IVoiceInteractionSession session,
4511 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4512 Bundle bOptions, int userId) {
4513 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4514 != PackageManager.PERMISSION_GRANTED) {
4515 String msg = "Permission Denial: startVoiceActivity() from pid="
4516 + Binder.getCallingPid()
4517 + ", uid=" + Binder.getCallingUid()
4518 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4520 throw new SecurityException(msg);
4522 if (session == null || interactor == null) {
4523 throw new NullPointerException("null session or interactor");
4525 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4526 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4527 // TODO: Switch to user app stacks here.
4528 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4529 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4530 null, bOptions, false, userId, null, null);
4534 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4535 throws RemoteException {
4536 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4537 synchronized (this) {
4538 ActivityRecord activity = getFocusedStack().topActivity();
4539 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4540 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4542 if (mRunningVoice != null || activity.task.voiceSession != null
4543 || activity.voiceSession != null) {
4544 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4547 if (activity.pendingVoiceInteractionStart) {
4548 Slog.w(TAG, "Pending start of voice interaction already.");
4551 activity.pendingVoiceInteractionStart = true;
4553 LocalServices.getService(VoiceInteractionManagerInternal.class)
4554 .startLocalVoiceInteraction(callingActivity, options);
4558 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4559 LocalServices.getService(VoiceInteractionManagerInternal.class)
4560 .stopLocalVoiceInteraction(callingActivity);
4564 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4565 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4566 .supportsLocalVoiceInteraction();
4569 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4570 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4571 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4572 if (activityToCallback == null) return;
4573 activityToCallback.setVoiceSessionLocked(voiceSession);
4575 // Inform the activity
4577 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4579 long token = Binder.clearCallingIdentity();
4581 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4583 Binder.restoreCallingIdentity(token);
4585 // TODO: VI Should we cache the activity so that it's easier to find later
4586 // rather than scan through all the stacks and activities?
4587 } catch (RemoteException re) {
4588 activityToCallback.clearVoiceSessionLocked();
4589 // TODO: VI Should this terminate the voice session?
4594 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4595 synchronized (this) {
4596 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4598 mVoiceWakeLock.acquire();
4600 mVoiceWakeLock.release();
4607 public boolean startNextMatchingActivity(IBinder callingActivity,
4608 Intent intent, Bundle bOptions) {
4609 // Refuse possible leaked file descriptors
4610 if (intent != null && intent.hasFileDescriptors() == true) {
4611 throw new IllegalArgumentException("File descriptors passed in Intent");
4613 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4615 synchronized (this) {
4616 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4618 ActivityOptions.abort(options);
4621 if (r.app == null || r.app.thread == null) {
4622 // The caller is not running... d'oh!
4623 ActivityOptions.abort(options);
4626 intent = new Intent(intent);
4627 // The caller is not allowed to change the data.
4628 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4629 // And we are resetting to find the next component...
4630 intent.setComponent(null);
4632 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4634 ActivityInfo aInfo = null;
4636 List<ResolveInfo> resolves =
4637 AppGlobals.getPackageManager().queryIntentActivities(
4638 intent, r.resolvedType,
4639 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4640 UserHandle.getCallingUserId()).getList();
4642 // Look for the original activity in the list...
4643 final int N = resolves != null ? resolves.size() : 0;
4644 for (int i=0; i<N; i++) {
4645 ResolveInfo rInfo = resolves.get(i);
4646 if (rInfo.activityInfo.packageName.equals(r.packageName)
4647 && rInfo.activityInfo.name.equals(r.info.name)) {
4648 // We found the current one... the next matching is
4652 aInfo = resolves.get(i).activityInfo;
4655 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4656 + "/" + r.info.name);
4657 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4658 ? "null" : aInfo.packageName + "/" + aInfo.name));
4663 } catch (RemoteException e) {
4666 if (aInfo == null) {
4667 // Nobody who is next!
4668 ActivityOptions.abort(options);
4669 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4673 intent.setComponent(new ComponentName(
4674 aInfo.applicationInfo.packageName, aInfo.name));
4675 intent.setFlags(intent.getFlags()&~(
4676 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4677 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4678 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4679 Intent.FLAG_ACTIVITY_NEW_TASK));
4681 // Okay now we need to start the new activity, replacing the
4682 // currently running activity. This is a little tricky because
4683 // we want to start the new one as if the current one is finished,
4684 // but not finish the current one first so that there is no flicker.
4686 final boolean wasFinishing = r.finishing;
4689 // Propagate reply information over to the new activity.
4690 final ActivityRecord resultTo = r.resultTo;
4691 final String resultWho = r.resultWho;
4692 final int requestCode = r.requestCode;
4694 if (resultTo != null) {
4695 resultTo.removeResultsLocked(r, resultWho, requestCode);
4698 final long origId = Binder.clearCallingIdentity();
4699 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4700 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4701 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4702 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4703 false, false, null, null, null);
4704 Binder.restoreCallingIdentity(origId);
4706 r.finishing = wasFinishing;
4707 if (res != ActivityManager.START_SUCCESS) {
4715 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4716 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4717 String msg = "Permission Denial: startActivityFromRecents called without " +
4718 START_TASKS_FROM_RECENTS;
4720 throw new SecurityException(msg);
4722 final long origId = Binder.clearCallingIdentity();
4724 synchronized (this) {
4725 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4728 Binder.restoreCallingIdentity(origId);
4732 final int startActivityInPackage(int uid, String callingPackage,
4733 Intent intent, String resolvedType, IBinder resultTo,
4734 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4735 IActivityContainer container, TaskRecord inTask) {
4737 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4738 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4740 // TODO: Switch to user app stacks here.
4741 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4742 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4743 null, null, null, bOptions, false, userId, container, inTask);
4748 public final int startActivities(IApplicationThread caller, String callingPackage,
4749 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4751 enforceNotIsolatedCaller("startActivities");
4752 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4753 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4754 // TODO: Switch to user app stacks here.
4755 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4756 resolvedTypes, resultTo, bOptions, userId);
4760 final int startActivitiesInPackage(int uid, String callingPackage,
4761 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4762 Bundle bOptions, int userId) {
4764 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4765 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4766 // TODO: Switch to user app stacks here.
4767 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4768 resultTo, bOptions, userId);
4773 public void reportActivityFullyDrawn(IBinder token) {
4774 synchronized (this) {
4775 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4779 r.reportFullyDrawnLocked();
4784 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4785 synchronized (this) {
4786 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4790 TaskRecord task = r.task;
4791 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4792 // Fixed screen orientation isn't supported when activities aren't in full screen
4796 final long origId = Binder.clearCallingIdentity();
4797 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4798 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4799 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4800 if (config != null) {
4801 r.frozenBeforeDestroy = true;
4802 if (!updateConfigurationLocked(config, r, false)) {
4803 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4806 Binder.restoreCallingIdentity(origId);
4811 public int getRequestedOrientation(IBinder token) {
4812 synchronized (this) {
4813 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4815 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4817 return mWindowManager.getAppOrientation(r.appToken);
4822 * This is the internal entry point for handling Activity.finish().
4824 * @param token The Binder token referencing the Activity we want to finish.
4825 * @param resultCode Result code, if any, from this Activity.
4826 * @param resultData Result data (Intent), if any, from this Activity.
4827 * @param finishTask Whether to finish the task associated with this Activity.
4829 * @return Returns true if the activity successfully finished, or false if it is still running.
4832 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4834 // Refuse possible leaked file descriptors
4835 if (resultData != null && resultData.hasFileDescriptors() == true) {
4836 throw new IllegalArgumentException("File descriptors passed in Intent");
4839 synchronized(this) {
4840 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4844 // Keep track of the root activity of the task before we finish it
4845 TaskRecord tr = r.task;
4846 ActivityRecord rootR = tr.getRootActivity();
4847 if (rootR == null) {
4848 Slog.w(TAG, "Finishing task with all activities already finished");
4850 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4852 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4853 mStackSupervisor.isLastLockedTask(tr)) {
4854 Slog.i(TAG, "Not finishing task in lock task mode");
4855 mStackSupervisor.showLockTaskToast();
4858 if (mController != null) {
4859 // Find the first activity that is not finishing.
4860 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4862 // ask watcher if this is allowed
4863 boolean resumeOK = true;
4865 resumeOK = mController.activityResuming(next.packageName);
4866 } catch (RemoteException e) {
4868 Watchdog.getInstance().setActivityController(null);
4872 Slog.i(TAG, "Not finishing activity because controller resumed");
4877 final long origId = Binder.clearCallingIdentity();
4880 final boolean finishWithRootActivity =
4881 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4882 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4883 || (finishWithRootActivity && r == rootR)) {
4884 // If requested, remove the task that is associated to this activity only if it
4885 // was the root activity in the task. The result code and data is ignored
4886 // because we don't support returning them across task boundaries. Also, to
4887 // keep backwards compatibility we remove the task from recents when finishing
4888 // task with root activity.
4889 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4891 Slog.i(TAG, "Removing task failed to finish activity");
4894 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4895 resultData, "app-request", true);
4897 Slog.i(TAG, "Failed to finish by app-request");
4902 Binder.restoreCallingIdentity(origId);
4908 public final void finishHeavyWeightApp() {
4909 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4910 != PackageManager.PERMISSION_GRANTED) {
4911 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4912 + Binder.getCallingPid()
4913 + ", uid=" + Binder.getCallingUid()
4914 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4916 throw new SecurityException(msg);
4919 synchronized(this) {
4920 if (mHeavyWeightProcess == null) {
4924 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4925 for (int i = 0; i < activities.size(); i++) {
4926 ActivityRecord r = activities.get(i);
4927 if (!r.finishing && r.isInStackLocked()) {
4928 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4929 null, "finish-heavy", true);
4933 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4934 mHeavyWeightProcess.userId, 0));
4935 mHeavyWeightProcess = null;
4940 public void crashApplication(int uid, int initialPid, String packageName,
4942 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4943 != PackageManager.PERMISSION_GRANTED) {
4944 String msg = "Permission Denial: crashApplication() from pid="
4945 + Binder.getCallingPid()
4946 + ", uid=" + Binder.getCallingUid()
4947 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4949 throw new SecurityException(msg);
4952 synchronized(this) {
4953 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4958 public final void finishSubActivity(IBinder token, String resultWho,
4960 synchronized(this) {
4961 final long origId = Binder.clearCallingIdentity();
4962 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4964 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4966 Binder.restoreCallingIdentity(origId);
4971 public boolean finishActivityAffinity(IBinder token) {
4972 synchronized(this) {
4973 final long origId = Binder.clearCallingIdentity();
4975 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4980 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4982 final TaskRecord task = r.task;
4983 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4984 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4985 mStackSupervisor.showLockTaskToast();
4988 return task.stack.finishActivityAffinityLocked(r);
4990 Binder.restoreCallingIdentity(origId);
4996 public void finishVoiceTask(IVoiceInteractionSession session) {
4997 synchronized (this) {
4998 final long origId = Binder.clearCallingIdentity();
5000 // TODO: VI Consider treating local voice interactions and voice tasks
5002 mStackSupervisor.finishVoiceTask(session);
5004 Binder.restoreCallingIdentity(origId);
5011 public boolean releaseActivityInstance(IBinder token) {
5012 synchronized(this) {
5013 final long origId = Binder.clearCallingIdentity();
5015 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5019 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5021 Binder.restoreCallingIdentity(origId);
5027 public void releaseSomeActivities(IApplicationThread appInt) {
5028 synchronized(this) {
5029 final long origId = Binder.clearCallingIdentity();
5031 ProcessRecord app = getRecordForAppLocked(appInt);
5032 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5034 Binder.restoreCallingIdentity(origId);
5040 public boolean willActivityBeVisible(IBinder token) {
5041 synchronized(this) {
5042 ActivityStack stack = ActivityRecord.getStackLocked(token);
5043 if (stack != null) {
5044 return stack.willActivityBeVisibleLocked(token);
5051 public void overridePendingTransition(IBinder token, String packageName,
5052 int enterAnim, int exitAnim) {
5053 synchronized(this) {
5054 ActivityRecord self = ActivityRecord.isInStackLocked(token);
5059 final long origId = Binder.clearCallingIdentity();
5061 if (self.state == ActivityState.RESUMED
5062 || self.state == ActivityState.PAUSING) {
5063 mWindowManager.overridePendingAppTransition(packageName,
5064 enterAnim, exitAnim, null);
5067 Binder.restoreCallingIdentity(origId);
5072 * Main function for removing an existing process from the activity manager
5073 * as a result of that process going away. Clears out all connections
5076 private final void handleAppDiedLocked(ProcessRecord app,
5077 boolean restarting, boolean allowRestart) {
5079 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5080 false /*replacingPid*/);
5081 if (!kept && !restarting) {
5082 removeLruProcessLocked(app);
5084 ProcessList.remove(pid);
5088 if (mProfileProc == app) {
5089 clearProfilerLocked();
5092 // Remove this application's activities from active lists.
5093 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5095 app.activities.clear();
5097 if (app.instrumentationClass != null) {
5098 Slog.w(TAG, "Crash of app " + app.processName
5099 + " running instrumentation " + app.instrumentationClass);
5100 Bundle info = new Bundle();
5101 info.putString("shortMsg", "Process crashed.");
5102 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5105 if (!restarting && hasVisibleActivities
5106 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5107 // If there was nothing to resume, and we are not already restarting this process, but
5108 // there is a visible activity that is hosted by the process... then make sure all
5109 // visible activities are running, taking care of restarting this process.
5110 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5114 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5115 IBinder threadBinder = thread.asBinder();
5116 // Find the application record.
5117 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5118 ProcessRecord rec = mLruProcesses.get(i);
5119 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5126 final ProcessRecord getRecordForAppLocked(
5127 IApplicationThread thread) {
5128 if (thread == null) {
5132 int appIndex = getLRURecordIndexForAppLocked(thread);
5133 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5136 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5137 // If there are no longer any background processes running,
5138 // and the app that died was not running instrumentation,
5139 // then tell everyone we are now low on memory.
5140 boolean haveBg = false;
5141 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5142 ProcessRecord rec = mLruProcesses.get(i);
5143 if (rec.thread != null
5144 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5151 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5153 long now = SystemClock.uptimeMillis();
5154 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5157 mLastMemUsageReportTime = now;
5160 final ArrayList<ProcessMemInfo> memInfos
5161 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5162 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5163 long now = SystemClock.uptimeMillis();
5164 for (int i=mLruProcesses.size()-1; i>=0; i--) {
5165 ProcessRecord rec = mLruProcesses.get(i);
5166 if (rec == dyingProc || rec.thread == null) {
5170 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5171 rec.setProcState, rec.adjType, rec.makeAdjReason()));
5173 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5174 // The low memory report is overriding any current
5175 // state for a GC request. Make sure to do
5176 // heavy/important/visible/foreground processes first.
5177 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5178 rec.lastRequestedGc = 0;
5180 rec.lastRequestedGc = rec.lastLowMemory;
5182 rec.reportLowMemory = true;
5183 rec.lastLowMemory = now;
5184 mProcessesToGc.remove(rec);
5185 addProcessToGcListLocked(rec);
5189 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5190 mHandler.sendMessage(msg);
5192 scheduleAppGcsLocked();
5196 final void appDiedLocked(ProcessRecord app) {
5197 appDiedLocked(app, app.pid, app.thread, false);
5200 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5201 boolean fromBinderDied) {
5202 // First check if this ProcessRecord is actually active for the pid.
5203 synchronized (mPidsSelfLocked) {
5204 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5205 if (curProc != app) {
5206 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5211 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5212 synchronized (stats) {
5213 stats.noteProcessDiedLocked(app.info.uid, pid);
5217 if (!fromBinderDied) {
5218 Process.killProcessQuiet(pid);
5220 killProcessGroup(app.uid, pid);
5224 // Clean up already done if the process has been re-started.
5225 if (app.pid == pid && app.thread != null &&
5226 app.thread.asBinder() == thread.asBinder()) {
5227 boolean doLowMem = app.instrumentationClass == null;
5228 boolean doOomAdj = doLowMem;
5229 if (!app.killedByAm) {
5230 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5232 mAllowLowerMemLevel = true;
5234 // Note that we always want to do oom adj to update our state with the
5235 // new number of procs.
5236 mAllowLowerMemLevel = false;
5239 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5240 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5241 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5242 handleAppDiedLocked(app, false, true);
5245 updateOomAdjLocked();
5248 doLowMemReportIfNeededLocked(app);
5250 } else if (app.pid != pid) {
5251 // A new process has already been started.
5252 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5253 + ") has died and restarted (pid " + app.pid + ").");
5254 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5255 } else if (DEBUG_PROCESSES) {
5256 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5257 + thread.asBinder());
5262 * If a stack trace dump file is configured, dump process stack traces.
5263 * @param clearTraces causes the dump file to be erased prior to the new
5264 * traces being written, if true; when false, the new traces will be
5265 * appended to any existing file content.
5266 * @param firstPids of dalvik VM processes to dump stack traces for first
5267 * @param lastPids of dalvik VM processes to dump stack traces for last
5268 * @param nativeProcs optional list of native process names to dump stack crawls
5269 * @return file containing stack traces, or null if no dump file is configured
5271 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5272 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5273 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5274 if (tracesPath == null || tracesPath.length() == 0) {
5278 File tracesFile = new File(tracesPath);
5280 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5281 tracesFile.createNewFile();
5282 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5283 } catch (IOException e) {
5284 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5288 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5292 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5293 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5294 // Use a FileObserver to detect when traces finish writing.
5295 // The order of traces is considered important to maintain for legibility.
5296 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5298 public synchronized void onEvent(int event, String path) { notify(); }
5302 observer.startWatching();
5304 // First collect all of the stacks of the most important pids.
5305 if (firstPids != null) {
5307 int num = firstPids.size();
5308 for (int i = 0; i < num; i++) {
5309 synchronized (observer) {
5310 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5311 + firstPids.get(i));
5312 final long sime = SystemClock.elapsedRealtime();
5313 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5314 observer.wait(1000); // Wait for write-close, give up after 1 sec
5315 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5316 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5319 } catch (InterruptedException e) {
5324 // Next collect the stacks of the native pids
5325 if (nativeProcs != null) {
5326 int[] pids = Process.getPidsForCommands(nativeProcs);
5328 for (int pid : pids) {
5329 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5330 final long sime = SystemClock.elapsedRealtime();
5331 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5332 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5333 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5338 // Lastly, measure CPU usage.
5339 if (processCpuTracker != null) {
5340 processCpuTracker.init();
5342 processCpuTracker.update();
5344 synchronized (processCpuTracker) {
5345 processCpuTracker.wait(500); // measure over 1/2 second.
5347 } catch (InterruptedException e) {
5349 processCpuTracker.update();
5351 // We'll take the stack crawls of just the top apps using CPU.
5352 final int N = processCpuTracker.countWorkingStats();
5354 for (int i=0; i<N && numProcs<5; i++) {
5355 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5356 if (lastPids.indexOfKey(stats.pid) >= 0) {
5359 synchronized (observer) {
5360 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5362 final long stime = SystemClock.elapsedRealtime();
5363 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5364 observer.wait(1000); // Wait for write-close, give up after 1 sec
5365 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5366 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5368 } catch (InterruptedException e) {
5371 } else if (DEBUG_ANR) {
5372 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5378 observer.stopWatching();
5382 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5383 if (true || IS_USER_BUILD) {
5386 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5387 if (tracesPath == null || tracesPath.length() == 0) {
5391 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5392 StrictMode.allowThreadDiskWrites();
5394 final File tracesFile = new File(tracesPath);
5395 final File tracesDir = tracesFile.getParentFile();
5396 final File tracesTmp = new File(tracesDir, "__tmp__");
5398 if (tracesFile.exists()) {
5400 tracesFile.renameTo(tracesTmp);
5402 StringBuilder sb = new StringBuilder();
5403 Time tobj = new Time();
5404 tobj.set(System.currentTimeMillis());
5405 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5407 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5408 sb.append(" since ");
5410 FileOutputStream fos = new FileOutputStream(tracesFile);
5411 fos.write(sb.toString().getBytes());
5413 fos.write("\n*** No application process!".getBytes());
5416 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5417 } catch (IOException e) {
5418 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5423 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5424 firstPids.add(app.pid);
5425 dumpStackTraces(tracesPath, firstPids, null, null, null);
5428 File lastTracesFile = null;
5429 File curTracesFile = null;
5430 for (int i=9; i>=0; i--) {
5431 String name = String.format(Locale.US, "slow%02d.txt", i);
5432 curTracesFile = new File(tracesDir, name);
5433 if (curTracesFile.exists()) {
5434 if (lastTracesFile != null) {
5435 curTracesFile.renameTo(lastTracesFile);
5437 curTracesFile.delete();
5440 lastTracesFile = curTracesFile;
5442 tracesFile.renameTo(curTracesFile);
5443 if (tracesTmp.exists()) {
5444 tracesTmp.renameTo(tracesFile);
5447 StrictMode.setThreadPolicy(oldPolicy);
5451 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5452 if (!mLaunchWarningShown) {
5453 mLaunchWarningShown = true;
5454 mUiHandler.post(new Runnable() {
5457 synchronized (ActivityManagerService.this) {
5458 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5460 mUiHandler.postDelayed(new Runnable() {
5463 synchronized (ActivityManagerService.this) {
5465 mLaunchWarningShown = false;
5476 public boolean clearApplicationUserData(final String packageName,
5477 final IPackageDataObserver observer, int userId) {
5478 enforceNotIsolatedCaller("clearApplicationUserData");
5479 int uid = Binder.getCallingUid();
5480 int pid = Binder.getCallingPid();
5481 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5482 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5485 long callingId = Binder.clearCallingIdentity();
5487 IPackageManager pm = AppGlobals.getPackageManager();
5489 synchronized(this) {
5490 if (getPackageManagerInternalLocked().isPackageDataProtected(
5491 userId, packageName)) {
5492 throw new SecurityException(
5493 "Cannot clear data for a protected package: " + packageName);
5497 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5498 } catch (RemoteException e) {
5501 Slog.w(TAG, "Invalid packageName: " + packageName);
5502 if (observer != null) {
5504 observer.onRemoveCompleted(packageName, false);
5505 } catch (RemoteException e) {
5506 Slog.i(TAG, "Observer no longer exists.");
5511 if (uid == pkgUid || checkComponentPermission(
5512 android.Manifest.permission.CLEAR_APP_USER_DATA,
5514 == PackageManager.PERMISSION_GRANTED) {
5515 forceStopPackageLocked(packageName, pkgUid, "clear data");
5517 throw new SecurityException("PID " + pid + " does not have permission "
5518 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5519 + " of package " + packageName);
5522 // Remove all tasks match the cleared application package and user
5523 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5524 final TaskRecord tr = mRecentTasks.get(i);
5525 final String taskPackageName =
5526 tr.getBaseIntent().getComponent().getPackageName();
5527 if (tr.userId != userId) continue;
5528 if (!taskPackageName.equals(packageName)) continue;
5529 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5533 final int pkgUidF = pkgUid;
5534 final int userIdF = userId;
5535 final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5537 public void onRemoveCompleted(String packageName, boolean succeeded)
5538 throws RemoteException {
5539 synchronized (ActivityManagerService.this) {
5540 finishForceStopPackageLocked(packageName, pkgUidF);
5543 final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5544 Uri.fromParts("package", packageName, null));
5545 intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5546 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5547 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5548 null, null, 0, null, null, null, null, false, false, userIdF);
5550 if (observer != null) {
5551 observer.onRemoveCompleted(packageName, succeeded);
5557 // Clear application user data
5558 pm.clearApplicationUserData(packageName, localObserver, userId);
5560 synchronized(this) {
5561 // Remove all permissions granted from/to this package
5562 removeUriPermissionsForPackageLocked(packageName, userId, true);
5565 // Remove all zen rules created by this package; revoke it's zen access.
5566 INotificationManager inm = NotificationManager.getService();
5567 inm.removeAutomaticZenRules(packageName);
5568 inm.setNotificationPolicyAccessGranted(packageName, false);
5570 } catch (RemoteException e) {
5573 Binder.restoreCallingIdentity(callingId);
5579 public void killBackgroundProcesses(final String packageName, int userId) {
5580 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5581 != PackageManager.PERMISSION_GRANTED &&
5582 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5583 != PackageManager.PERMISSION_GRANTED) {
5584 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5585 + Binder.getCallingPid()
5586 + ", uid=" + Binder.getCallingUid()
5587 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5589 throw new SecurityException(msg);
5592 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5593 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5594 long callingId = Binder.clearCallingIdentity();
5596 IPackageManager pm = AppGlobals.getPackageManager();
5597 synchronized(this) {
5600 appId = UserHandle.getAppId(
5601 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5602 } catch (RemoteException e) {
5605 Slog.w(TAG, "Invalid packageName: " + packageName);
5608 killPackageProcessesLocked(packageName, appId, userId,
5609 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5612 Binder.restoreCallingIdentity(callingId);
5617 public void killAllBackgroundProcesses() {
5618 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5619 != PackageManager.PERMISSION_GRANTED) {
5620 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5621 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5622 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5624 throw new SecurityException(msg);
5627 final long callingId = Binder.clearCallingIdentity();
5629 synchronized (this) {
5630 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5631 final int NP = mProcessNames.getMap().size();
5632 for (int ip = 0; ip < NP; ip++) {
5633 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5634 final int NA = apps.size();
5635 for (int ia = 0; ia < NA; ia++) {
5636 final ProcessRecord app = apps.valueAt(ia);
5637 if (app.persistent) {
5638 // We don't kill persistent processes.
5643 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5650 final int N = procs.size();
5651 for (int i = 0; i < N; i++) {
5652 removeProcessLocked(procs.get(i), false, true, "kill all background");
5655 mAllowLowerMemLevel = true;
5657 updateOomAdjLocked();
5658 doLowMemReportIfNeededLocked(null);
5661 Binder.restoreCallingIdentity(callingId);
5666 * Kills all background processes, except those matching any of the
5667 * specified properties.
5669 * @param minTargetSdk the target SDK version at or above which to preserve
5670 * processes, or {@code -1} to ignore the target SDK
5671 * @param maxProcState the process state at or below which to preserve
5672 * processes, or {@code -1} to ignore the process state
5674 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5675 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5676 != PackageManager.PERMISSION_GRANTED) {
5677 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5678 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5679 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5681 throw new SecurityException(msg);
5684 final long callingId = Binder.clearCallingIdentity();
5686 synchronized (this) {
5687 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5688 final int NP = mProcessNames.getMap().size();
5689 for (int ip = 0; ip < NP; ip++) {
5690 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5691 final int NA = apps.size();
5692 for (int ia = 0; ia < NA; ia++) {
5693 final ProcessRecord app = apps.valueAt(ia);
5696 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5697 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5704 final int N = procs.size();
5705 for (int i = 0; i < N; i++) {
5706 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5710 Binder.restoreCallingIdentity(callingId);
5715 public void forceStopPackage(final String packageName, int userId) {
5716 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5717 != PackageManager.PERMISSION_GRANTED) {
5718 String msg = "Permission Denial: forceStopPackage() from pid="
5719 + Binder.getCallingPid()
5720 + ", uid=" + Binder.getCallingUid()
5721 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5723 throw new SecurityException(msg);
5725 final int callingPid = Binder.getCallingPid();
5726 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5727 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5728 long callingId = Binder.clearCallingIdentity();
5730 IPackageManager pm = AppGlobals.getPackageManager();
5731 synchronized(this) {
5732 int[] users = userId == UserHandle.USER_ALL
5733 ? mUserController.getUsers() : new int[] { userId };
5734 for (int user : users) {
5737 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5739 } catch (RemoteException e) {
5742 Slog.w(TAG, "Invalid packageName: " + packageName);
5746 pm.setPackageStoppedState(packageName, true, user);
5747 } catch (RemoteException e) {
5748 } catch (IllegalArgumentException e) {
5749 Slog.w(TAG, "Failed trying to unstop package "
5750 + packageName + ": " + e);
5752 if (mUserController.isUserRunningLocked(user, 0)) {
5753 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5754 finishForceStopPackageLocked(packageName, pkgUid);
5759 Binder.restoreCallingIdentity(callingId);
5764 public void addPackageDependency(String packageName) {
5765 synchronized (this) {
5766 int callingPid = Binder.getCallingPid();
5767 if (callingPid == Process.myPid()) {
5772 synchronized (mPidsSelfLocked) {
5773 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5776 if (proc.pkgDeps == null) {
5777 proc.pkgDeps = new ArraySet<String>(1);
5779 proc.pkgDeps.add(packageName);
5785 * The pkg name and app id have to be specified.
5788 public void killApplication(String pkg, int appId, int userId, String reason) {
5792 // Make sure the uid is valid.
5794 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5797 int callerUid = Binder.getCallingUid();
5798 // Only the system server can kill an application
5799 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5800 // Post an aysnc message to kill the application
5801 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5804 Bundle bundle = new Bundle();
5805 bundle.putString("pkg", pkg);
5806 bundle.putString("reason", reason);
5808 mHandler.sendMessage(msg);
5810 throw new SecurityException(callerUid + " cannot kill pkg: " +
5816 public void closeSystemDialogs(String reason) {
5817 enforceNotIsolatedCaller("closeSystemDialogs");
5819 final int pid = Binder.getCallingPid();
5820 final int uid = Binder.getCallingUid();
5821 final long origId = Binder.clearCallingIdentity();
5823 synchronized (this) {
5824 // Only allow this from foreground processes, so that background
5825 // applications can't abuse it to prevent system UI from being shown.
5826 if (uid >= Process.FIRST_APPLICATION_UID) {
5828 synchronized (mPidsSelfLocked) {
5829 proc = mPidsSelfLocked.get(pid);
5831 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5832 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5833 + " from background process " + proc);
5837 closeSystemDialogsLocked(reason);
5840 Binder.restoreCallingIdentity(origId);
5844 void closeSystemDialogsLocked(String reason) {
5845 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5846 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5847 | Intent.FLAG_RECEIVER_FOREGROUND);
5848 if (reason != null) {
5849 intent.putExtra("reason", reason);
5851 mWindowManager.closeSystemDialogs(reason);
5853 mStackSupervisor.closeSystemDialogsLocked();
5855 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5856 AppOpsManager.OP_NONE, null, false, false,
5857 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5861 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5862 enforceNotIsolatedCaller("getProcessMemoryInfo");
5863 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5864 for (int i=pids.length-1; i>=0; i--) {
5867 synchronized (this) {
5868 synchronized (mPidsSelfLocked) {
5869 proc = mPidsSelfLocked.get(pids[i]);
5870 oomAdj = proc != null ? proc.setAdj : 0;
5873 infos[i] = new Debug.MemoryInfo();
5874 Debug.getMemoryInfo(pids[i], infos[i]);
5876 synchronized (this) {
5877 if (proc.thread != null && proc.setAdj == oomAdj) {
5878 // Record this for posterity if the process has been stable.
5879 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5880 infos[i].getTotalUss(), false, proc.pkgList);
5889 public long[] getProcessPss(int[] pids) {
5890 enforceNotIsolatedCaller("getProcessPss");
5891 long[] pss = new long[pids.length];
5892 for (int i=pids.length-1; i>=0; i--) {
5895 synchronized (this) {
5896 synchronized (mPidsSelfLocked) {
5897 proc = mPidsSelfLocked.get(pids[i]);
5898 oomAdj = proc != null ? proc.setAdj : 0;
5901 long[] tmpUss = new long[1];
5902 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5904 synchronized (this) {
5905 if (proc.thread != null && proc.setAdj == oomAdj) {
5906 // Record this for posterity if the process has been stable.
5907 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5916 public void killApplicationProcess(String processName, int uid) {
5917 if (processName == null) {
5921 int callerUid = Binder.getCallingUid();
5922 // Only the system server can kill an application
5923 if (callerUid == Process.SYSTEM_UID) {
5924 synchronized (this) {
5925 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5926 if (app != null && app.thread != null) {
5928 app.thread.scheduleSuicide();
5929 } catch (RemoteException e) {
5930 // If the other end already died, then our work here is done.
5933 Slog.w(TAG, "Process/uid not found attempting kill of "
5934 + processName + " / " + uid);
5938 throw new SecurityException(callerUid + " cannot kill app process: " +
5943 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5944 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5945 false, true, false, false, UserHandle.getUserId(uid), reason);
5948 private void finishForceStopPackageLocked(final String packageName, int uid) {
5949 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5950 Uri.fromParts("package", packageName, null));
5951 if (!mProcessesReady) {
5952 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5953 | Intent.FLAG_RECEIVER_FOREGROUND);
5955 intent.putExtra(Intent.EXTRA_UID, uid);
5956 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5957 broadcastIntentLocked(null, null, intent,
5958 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5959 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5963 private final boolean killPackageProcessesLocked(String packageName, int appId,
5964 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5965 boolean doit, boolean evenPersistent, String reason) {
5966 ArrayList<ProcessRecord> procs = new ArrayList<>();
5968 // Remove all processes this package may have touched: all with the
5969 // same UID (except for the system or root user), and all whose name
5970 // matches the package name.
5971 final int NP = mProcessNames.getMap().size();
5972 for (int ip=0; ip<NP; ip++) {
5973 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5974 final int NA = apps.size();
5975 for (int ia=0; ia<NA; ia++) {
5976 ProcessRecord app = apps.valueAt(ia);
5977 if (app.persistent && !evenPersistent) {
5978 // we don't kill persistent processes
5988 // Skip process if it doesn't meet our oom adj requirement.
5989 if (app.setAdj < minOomAdj) {
5993 // If no package is specified, we call all processes under the
5995 if (packageName == null) {
5996 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5999 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6002 // Package has been specified, we want to hit all processes
6003 // that match it. We need to qualify this by the processes
6004 // that are running under the specified app and user ID.
6006 final boolean isDep = app.pkgDeps != null
6007 && app.pkgDeps.contains(packageName);
6008 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6011 if (userId != UserHandle.USER_ALL && app.userId != userId) {
6014 if (!app.pkgList.containsKey(packageName) && !isDep) {
6019 // Process has passed all conditions, kill it!
6028 int N = procs.size();
6029 for (int i=0; i<N; i++) {
6030 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6032 updateOomAdjLocked();
6036 private void cleanupDisabledPackageComponentsLocked(
6037 String packageName, int userId, boolean killProcess, String[] changedClasses) {
6039 Set<String> disabledClasses = null;
6040 boolean packageDisabled = false;
6041 IPackageManager pm = AppGlobals.getPackageManager();
6043 if (changedClasses == null) {
6044 // Nothing changed...
6048 // Determine enable/disable state of the package and its components.
6049 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6050 for (int i = changedClasses.length - 1; i >= 0; i--) {
6051 final String changedClass = changedClasses[i];
6053 if (changedClass.equals(packageName)) {
6055 // Entire package setting changed
6056 enabled = pm.getApplicationEnabledSetting(packageName,
6057 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6058 } catch (Exception e) {
6059 // No such package/component; probably racing with uninstall. In any
6060 // event it means we have nothing further to do here.
6063 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6064 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6065 if (packageDisabled) {
6066 // Entire package is disabled.
6067 // No need to continue to check component states.
6068 disabledClasses = null;
6073 enabled = pm.getComponentEnabledSetting(
6074 new ComponentName(packageName, changedClass),
6075 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6076 } catch (Exception e) {
6077 // As above, probably racing with uninstall.
6080 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6081 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6082 if (disabledClasses == null) {
6083 disabledClasses = new ArraySet<>(changedClasses.length);
6085 disabledClasses.add(changedClass);
6090 if (!packageDisabled && disabledClasses == null) {
6091 // Nothing to do here...
6095 // Clean-up disabled activities.
6096 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6097 packageName, disabledClasses, true, false, userId) && mBooted) {
6098 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6099 mStackSupervisor.scheduleIdleLocked();
6102 // Clean-up disabled tasks
6103 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6105 // Clean-up disabled services.
6106 mServices.bringDownDisabledPackageServicesLocked(
6107 packageName, disabledClasses, userId, false, killProcess, true);
6109 // Clean-up disabled providers.
6110 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6111 mProviderMap.collectPackageProvidersLocked(
6112 packageName, disabledClasses, true, false, userId, providers);
6113 for (int i = providers.size() - 1; i >= 0; i--) {
6114 removeDyingProviderLocked(null, providers.get(i), true);
6117 // Clean-up disabled broadcast receivers.
6118 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6119 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6120 packageName, disabledClasses, userId, true);
6125 final boolean clearBroadcastQueueForUserLocked(int userId) {
6126 boolean didSomething = false;
6127 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6128 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6129 null, null, userId, true);
6131 return didSomething;
6134 final boolean forceStopPackageLocked(String packageName, int appId,
6135 boolean callerWillRestart, boolean purgeCache, boolean doit,
6136 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6139 if (userId == UserHandle.USER_ALL && packageName == null) {
6140 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6143 if (appId < 0 && packageName != null) {
6145 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6146 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6147 } catch (RemoteException e) {
6152 if (packageName != null) {
6153 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6154 + " user=" + userId + ": " + reason);
6156 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6159 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6162 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6163 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6164 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6166 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6167 packageName, null, doit, evenPersistent, userId)) {
6171 didSomething = true;
6174 if (mServices.bringDownDisabledPackageServicesLocked(
6175 packageName, null, userId, evenPersistent, true, doit)) {
6179 didSomething = true;
6182 if (packageName == null) {
6183 // Remove all sticky broadcasts from this user.
6184 mStickyBroadcasts.remove(userId);
6187 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6188 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6189 userId, providers)) {
6193 didSomething = true;
6195 for (i = providers.size() - 1; i >= 0; i--) {
6196 removeDyingProviderLocked(null, providers.get(i), true);
6199 // Remove transient permissions granted from/to this package/user
6200 removeUriPermissionsForPackageLocked(packageName, userId, false);
6203 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6204 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6205 packageName, null, userId, doit);
6209 if (packageName == null || uninstalling) {
6210 // Remove pending intents. For now we only do this when force
6211 // stopping users, because we have some problems when doing this
6212 // for packages -- app widgets are not currently cleaned up for
6213 // such packages, so they can be left with bad pending intents.
6214 if (mIntentSenderRecords.size() > 0) {
6215 Iterator<WeakReference<PendingIntentRecord>> it
6216 = mIntentSenderRecords.values().iterator();
6217 while (it.hasNext()) {
6218 WeakReference<PendingIntentRecord> wpir = it.next();
6223 PendingIntentRecord pir = wpir.get();
6228 if (packageName == null) {
6229 // Stopping user, remove all objects for the user.
6230 if (pir.key.userId != userId) {
6231 // Not the same user, skip it.
6235 if (UserHandle.getAppId(pir.uid) != appId) {
6236 // Different app id, skip it.
6239 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6240 // Different user, skip it.
6243 if (!pir.key.packageName.equals(packageName)) {
6244 // Different package, skip it.
6251 didSomething = true;
6253 pir.canceled = true;
6254 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6255 pir.key.activity.pendingResults.remove(pir.ref);
6262 if (purgeCache && packageName != null) {
6263 AttributeCache ac = AttributeCache.instance();
6265 ac.removePackage(packageName);
6269 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6270 mStackSupervisor.scheduleIdleLocked();
6274 return didSomething;
6277 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6278 ProcessRecord old = mProcessNames.remove(name, uid);
6280 old.uidRecord.numProcs--;
6281 if (old.uidRecord.numProcs == 0) {
6282 // No more processes using this uid, tell clients it is gone.
6283 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6284 "No more processes in " + old.uidRecord);
6285 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6286 mActiveUids.remove(uid);
6287 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6289 old.uidRecord = null;
6291 mIsolatedProcesses.remove(uid);
6295 private final void addProcessNameLocked(ProcessRecord proc) {
6296 // We shouldn't already have a process under this name, but just in case we
6297 // need to clean up whatever may be there now.
6298 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6299 if (old == proc && proc.persistent) {
6300 // We are re-adding a persistent process. Whatevs! Just leave it there.
6301 Slog.w(TAG, "Re-adding persistent process " + proc);
6302 } else if (old != null) {
6303 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6305 UidRecord uidRec = mActiveUids.get(proc.uid);
6306 if (uidRec == null) {
6307 uidRec = new UidRecord(proc.uid);
6308 // This is the first appearance of the uid, report it now!
6309 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6310 "Creating new process uid: " + uidRec);
6311 mActiveUids.put(proc.uid, uidRec);
6312 noteUidProcessState(uidRec.uid, uidRec.curProcState);
6313 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6315 proc.uidRecord = uidRec;
6317 // Reset render thread tid if it was already set, so new process can set it again.
6318 proc.renderThreadTid = 0;
6320 mProcessNames.put(proc.processName, proc.uid, proc);
6321 if (proc.isolated) {
6322 mIsolatedProcesses.put(proc.uid, proc);
6326 boolean removeProcessLocked(ProcessRecord app,
6327 boolean callerWillRestart, boolean allowRestart, String reason) {
6328 final String name = app.processName;
6329 final int uid = app.uid;
6330 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6331 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6333 ProcessRecord old = mProcessNames.get(name, uid);
6335 // This process is no longer active, so nothing to do.
6336 Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6339 removeProcessNameLocked(name, uid);
6340 if (mHeavyWeightProcess == app) {
6341 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6342 mHeavyWeightProcess.userId, 0));
6343 mHeavyWeightProcess = null;
6345 boolean needRestart = false;
6346 if (app.pid > 0 && app.pid != MY_PID) {
6348 synchronized (mPidsSelfLocked) {
6349 mPidsSelfLocked.remove(pid);
6350 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6352 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6354 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6356 boolean willRestart = false;
6357 if (app.persistent && !app.isolated) {
6358 if (!callerWillRestart) {
6364 app.kill(reason, true);
6365 handleAppDiedLocked(app, willRestart, allowRestart);
6367 removeLruProcessLocked(app);
6368 addAppLocked(app.info, false, null /* ABI override */);
6371 mRemovedProcesses.add(app);
6377 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6378 cleanupAppInLaunchingProvidersLocked(app, true);
6379 removeProcessLocked(app, false, true, "timeout publishing content providers");
6382 private final void processStartTimedOutLocked(ProcessRecord app) {
6383 final int pid = app.pid;
6384 boolean gone = false;
6385 synchronized (mPidsSelfLocked) {
6386 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6387 if (knownApp != null && knownApp.thread == null) {
6388 mPidsSelfLocked.remove(pid);
6394 Slog.w(TAG, "Process " + app + " failed to attach");
6395 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6396 pid, app.uid, app.processName);
6397 removeProcessNameLocked(app.processName, app.uid);
6398 if (mHeavyWeightProcess == app) {
6399 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6400 mHeavyWeightProcess.userId, 0));
6401 mHeavyWeightProcess = null;
6403 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6405 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6407 // Take care of any launching providers waiting for this process.
6408 cleanupAppInLaunchingProvidersLocked(app, true);
6409 // Take care of any services that are waiting for the process.
6410 mServices.processStartTimedOutLocked(app);
6411 app.kill("start timeout", true);
6412 removeLruProcessLocked(app);
6413 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6414 Slog.w(TAG, "Unattached app died before backup, skipping");
6416 IBackupManager bm = IBackupManager.Stub.asInterface(
6417 ServiceManager.getService(Context.BACKUP_SERVICE));
6418 bm.agentDisconnected(app.info.packageName);
6419 } catch (RemoteException e) {
6420 // Can't happen; the backup manager is local
6423 if (isPendingBroadcastProcessLocked(pid)) {
6424 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6425 skipPendingBroadcastLocked(pid);
6428 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6432 private final boolean attachApplicationLocked(IApplicationThread thread,
6435 // Find the application record that is being attached... either via
6436 // the pid if we are running in multiple processes, or just pull the
6437 // next app record if we are emulating process with anonymous threads.
6439 if (pid != MY_PID && pid >= 0) {
6440 synchronized (mPidsSelfLocked) {
6441 app = mPidsSelfLocked.get(pid);
6448 Slog.w(TAG, "No pending application record for pid " + pid
6449 + " (IApplicationThread " + thread + "); dropping process");
6450 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6451 if (pid > 0 && pid != MY_PID) {
6452 Process.killProcessQuiet(pid);
6453 //TODO: killProcessGroup(app.info.uid, pid);
6456 thread.scheduleExit();
6457 } catch (Exception e) {
6458 // Ignore exceptions.
6464 // If this application record is still attached to a previous
6465 // process, clean it up now.
6466 if (app.thread != null) {
6467 handleAppDiedLocked(app, true, true);
6470 // Tell the process all about itself.
6472 if (DEBUG_ALL) Slog.v(
6473 TAG, "Binding process pid " + pid + " to record " + app);
6475 final String processName = app.processName;
6477 AppDeathRecipient adr = new AppDeathRecipient(
6479 thread.asBinder().linkToDeath(adr, 0);
6480 app.deathRecipient = adr;
6481 } catch (RemoteException e) {
6482 app.resetPackageList(mProcessStats);
6483 startProcessLocked(app, "link fail", processName);
6487 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6489 app.makeActive(thread, mProcessStats);
6490 app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6491 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6492 app.forcingToForeground = null;
6493 updateProcessForegroundLocked(app, false, false);
6494 app.hasShownUi = false;
6495 app.debugging = false;
6497 app.killedByAm = false;
6499 // We carefully use the same state that PackageManager uses for
6500 // filtering, since we use this flag to decide if we need to install
6501 // providers when user is unlocked later
6502 app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6504 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6506 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6507 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6509 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6510 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6512 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6516 Slog.i(TAG, "Launching preboot mode app: " + app);
6519 if (DEBUG_ALL) Slog.v(
6520 TAG, "New app record " + app
6521 + " thread=" + thread.asBinder() + " pid=" + pid);
6523 int testMode = IApplicationThread.DEBUG_OFF;
6524 if (mDebugApp != null && mDebugApp.equals(processName)) {
6525 testMode = mWaitForDebugger
6526 ? IApplicationThread.DEBUG_WAIT
6527 : IApplicationThread.DEBUG_ON;
6528 app.debugging = true;
6529 if (mDebugTransient) {
6530 mDebugApp = mOrigDebugApp;
6531 mWaitForDebugger = mOrigWaitForDebugger;
6534 String profileFile = app.instrumentationProfileFile;
6535 ParcelFileDescriptor profileFd = null;
6536 int samplingInterval = 0;
6537 boolean profileAutoStop = false;
6538 if (mProfileApp != null && mProfileApp.equals(processName)) {
6540 profileFile = mProfileFile;
6541 profileFd = mProfileFd;
6542 samplingInterval = mSamplingInterval;
6543 profileAutoStop = mAutoStopProfiler;
6545 boolean enableTrackAllocation = false;
6546 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6547 enableTrackAllocation = true;
6548 mTrackAllocationApp = null;
6551 // If the app is being launched for restore or full backup, set it up specially
6552 boolean isRestrictedBackupMode = false;
6553 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6554 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6555 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6556 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6557 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6560 if (app.instrumentationClass != null) {
6561 notifyPackageUse(app.instrumentationClass.getPackageName(),
6562 PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6564 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6565 + processName + " with config " + mConfiguration);
6566 ApplicationInfo appInfo = app.instrumentationInfo != null
6567 ? app.instrumentationInfo : app.info;
6568 app.compat = compatibilityInfoForPackageLocked(appInfo);
6569 if (profileFd != null) {
6570 profileFd = profileFd.dup();
6572 ProfilerInfo profilerInfo = profileFile == null ? null
6573 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6574 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6575 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6576 app.instrumentationUiAutomationConnection, testMode,
6577 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6578 isRestrictedBackupMode || !normalMode, app.persistent,
6579 new Configuration(mConfiguration), app.compat,
6580 getCommonServicesLocked(app.isolated),
6581 mCoreSettingsObserver.getCoreSettingsLocked());
6582 updateLruProcessLocked(app, false, null);
6583 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6584 } catch (Exception e) {
6585 // todo: Yikes! What should we do? For now we will try to
6586 // start another process, but that could easily get us in
6587 // an infinite loop of restarting processes...
6588 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6590 app.resetPackageList(mProcessStats);
6591 app.unlinkDeathRecipient();
6592 startProcessLocked(app, "bind fail", processName);
6596 // Remove this record from the list of starting applications.
6597 mPersistentStartingProcesses.remove(app);
6598 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6599 "Attach application locked removing on hold: " + app);
6600 mProcessesOnHold.remove(app);
6602 boolean badApp = false;
6603 boolean didSomething = false;
6605 // See if the top visible activity is waiting to run in this process...
6608 if (mStackSupervisor.attachApplicationLocked(app)) {
6609 didSomething = true;
6611 } catch (Exception e) {
6612 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6617 // Find any services that should be running in this process...
6620 didSomething |= mServices.attachApplicationLocked(app, processName);
6621 } catch (Exception e) {
6622 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6627 // Check if a next-broadcast receiver is in this process...
6628 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6630 didSomething |= sendPendingBroadcastsLocked(app);
6631 } catch (Exception e) {
6632 // If the app died trying to launch the receiver we declare it 'bad'
6633 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6638 // Check whether the next backup agent is in this process...
6639 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6640 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6641 "New app is backup target, launching agent for " + app);
6642 notifyPackageUse(mBackupTarget.appInfo.packageName,
6643 PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6645 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6646 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6647 mBackupTarget.backupMode);
6648 } catch (Exception e) {
6649 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6655 app.kill("error during init", true);
6656 handleAppDiedLocked(app, false, true);
6660 if (!didSomething) {
6661 updateOomAdjLocked();
6668 public final void attachApplication(IApplicationThread thread) {
6669 synchronized (this) {
6670 int callingPid = Binder.getCallingPid();
6671 final long origId = Binder.clearCallingIdentity();
6672 attachApplicationLocked(thread, callingPid);
6673 Binder.restoreCallingIdentity(origId);
6678 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6679 final long origId = Binder.clearCallingIdentity();
6680 synchronized (this) {
6681 ActivityStack stack = ActivityRecord.getStackLocked(token);
6682 if (stack != null) {
6684 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6685 if (stopProfiling) {
6686 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6689 } catch (IOException e) {
6691 clearProfilerLocked();
6696 Binder.restoreCallingIdentity(origId);
6699 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6700 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6701 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6704 void enableScreenAfterBoot() {
6705 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6706 SystemClock.uptimeMillis());
6707 mWindowManager.enableScreenAfterBoot();
6709 synchronized (this) {
6710 updateEventDispatchingLocked();
6715 public void showBootMessage(final CharSequence msg, final boolean always) {
6716 if (Binder.getCallingUid() != Process.myUid()) {
6717 throw new SecurityException();
6719 mWindowManager.showBootMessage(msg, always);
6723 public void keyguardWaitingForActivityDrawn() {
6724 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6725 final long token = Binder.clearCallingIdentity();
6727 synchronized (this) {
6728 if (DEBUG_LOCKSCREEN) logLockScreen("");
6729 mWindowManager.keyguardWaitingForActivityDrawn();
6730 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6731 mLockScreenShown = LOCK_SCREEN_LEAVING;
6732 updateSleepIfNeededLocked();
6736 Binder.restoreCallingIdentity(token);
6741 public void keyguardGoingAway(int flags) {
6742 enforceNotIsolatedCaller("keyguardGoingAway");
6743 final long token = Binder.clearCallingIdentity();
6745 synchronized (this) {
6746 if (DEBUG_LOCKSCREEN) logLockScreen("");
6747 mWindowManager.keyguardGoingAway(flags);
6748 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6749 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6750 updateSleepIfNeededLocked();
6752 // Some stack visibility might change (e.g. docked stack)
6753 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6754 applyVrModeIfNeededLocked(mFocusedActivity, true);
6758 Binder.restoreCallingIdentity(token);
6762 final void finishBooting() {
6763 synchronized (this) {
6764 if (!mBootAnimationComplete) {
6765 mCallFinishBooting = true;
6768 mCallFinishBooting = false;
6771 ArraySet<String> completedIsas = new ArraySet<String>();
6772 for (String abi : Build.SUPPORTED_ABIS) {
6773 Process.establishZygoteConnectionForAbi(abi);
6774 final String instructionSet = VMRuntime.getInstructionSet(abi);
6775 if (!completedIsas.contains(instructionSet)) {
6777 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6778 } catch (InstallerException e) {
6779 Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6780 e.getMessage() +")");
6782 completedIsas.add(instructionSet);
6786 IntentFilter pkgFilter = new IntentFilter();
6787 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6788 pkgFilter.addDataScheme("package");
6789 mContext.registerReceiver(new BroadcastReceiver() {
6791 public void onReceive(Context context, Intent intent) {
6792 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6794 for (String pkg : pkgs) {
6795 synchronized (ActivityManagerService.this) {
6796 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6797 0, "query restart")) {
6798 setResultCode(Activity.RESULT_OK);
6807 IntentFilter dumpheapFilter = new IntentFilter();
6808 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6809 mContext.registerReceiver(new BroadcastReceiver() {
6811 public void onReceive(Context context, Intent intent) {
6812 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6813 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6815 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6820 // Let system services know.
6821 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6823 synchronized (this) {
6824 // Ensure that any processes we had put on hold are now started
6826 final int NP = mProcessesOnHold.size();
6828 ArrayList<ProcessRecord> procs =
6829 new ArrayList<ProcessRecord>(mProcessesOnHold);
6830 for (int ip=0; ip<NP; ip++) {
6831 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6833 startProcessLocked(procs.get(ip), "on-hold", null);
6837 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6838 // Start looking for apps that are abusing wake locks.
6839 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6840 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6841 // Tell anyone interested that we are done booting!
6842 SystemProperties.set("sys.boot_completed", "1");
6844 // And trigger dev.bootcomplete if we are not showing encryption progress
6845 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6846 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6847 SystemProperties.set("dev.bootcomplete", "1");
6849 mUserController.sendBootCompletedLocked(
6850 new IIntentReceiver.Stub() {
6852 public void performReceive(Intent intent, int resultCode,
6853 String data, Bundle extras, boolean ordered,
6854 boolean sticky, int sendingUser) {
6855 synchronized (ActivityManagerService.this) {
6856 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6861 scheduleStartProfilesLocked();
6867 public void bootAnimationComplete() {
6868 final boolean callFinishBooting;
6869 synchronized (this) {
6870 callFinishBooting = mCallFinishBooting;
6871 mBootAnimationComplete = true;
6873 if (callFinishBooting) {
6874 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6876 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6880 final void ensureBootCompleted() {
6882 boolean enableScreen;
6883 synchronized (this) {
6886 enableScreen = !mBooted;
6891 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6893 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6897 enableScreenAfterBoot();
6902 public final void activityResumed(IBinder token) {
6903 final long origId = Binder.clearCallingIdentity();
6904 synchronized(this) {
6905 ActivityStack stack = ActivityRecord.getStackLocked(token);
6906 if (stack != null) {
6907 stack.activityResumedLocked(token);
6910 Binder.restoreCallingIdentity(origId);
6914 public final void activityPaused(IBinder token) {
6915 final long origId = Binder.clearCallingIdentity();
6916 synchronized(this) {
6917 ActivityStack stack = ActivityRecord.getStackLocked(token);
6918 if (stack != null) {
6919 stack.activityPausedLocked(token, false);
6922 Binder.restoreCallingIdentity(origId);
6926 public final void activityStopped(IBinder token, Bundle icicle,
6927 PersistableBundle persistentState, CharSequence description) {
6928 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6930 // Refuse possible leaked file descriptors
6931 if (icicle != null && icicle.hasFileDescriptors()) {
6932 throw new IllegalArgumentException("File descriptors passed in Bundle");
6935 final long origId = Binder.clearCallingIdentity();
6937 synchronized (this) {
6938 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6940 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6946 Binder.restoreCallingIdentity(origId);
6950 public final void activityDestroyed(IBinder token) {
6951 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6952 synchronized (this) {
6953 ActivityStack stack = ActivityRecord.getStackLocked(token);
6954 if (stack != null) {
6955 stack.activityDestroyedLocked(token, "activityDestroyed");
6961 public final void activityRelaunched(IBinder token) {
6962 final long origId = Binder.clearCallingIdentity();
6963 synchronized (this) {
6964 mStackSupervisor.activityRelaunchedLocked(token);
6966 Binder.restoreCallingIdentity(origId);
6970 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6971 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6972 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6973 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6974 synchronized (this) {
6975 ActivityRecord record = ActivityRecord.isInStackLocked(token);
6976 if (record == null) {
6977 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6978 + "found for: " + token);
6980 record.setSizeConfigurations(horizontalSizeConfiguration,
6981 verticalSizeConfigurations, smallestSizeConfigurations);
6986 public final void backgroundResourcesReleased(IBinder token) {
6987 final long origId = Binder.clearCallingIdentity();
6989 synchronized (this) {
6990 ActivityStack stack = ActivityRecord.getStackLocked(token);
6991 if (stack != null) {
6992 stack.backgroundResourcesReleased();
6996 Binder.restoreCallingIdentity(origId);
7001 public final void notifyLaunchTaskBehindComplete(IBinder token) {
7002 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7006 public final void notifyEnterAnimationComplete(IBinder token) {
7007 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7011 public String getCallingPackage(IBinder token) {
7012 synchronized (this) {
7013 ActivityRecord r = getCallingRecordLocked(token);
7014 return r != null ? r.info.packageName : null;
7019 public ComponentName getCallingActivity(IBinder token) {
7020 synchronized (this) {
7021 ActivityRecord r = getCallingRecordLocked(token);
7022 return r != null ? r.intent.getComponent() : null;
7026 private ActivityRecord getCallingRecordLocked(IBinder token) {
7027 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7035 public ComponentName getActivityClassForToken(IBinder token) {
7036 synchronized(this) {
7037 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7041 return r.intent.getComponent();
7046 public String getPackageForToken(IBinder token) {
7047 synchronized(this) {
7048 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7052 return r.packageName;
7057 public boolean isRootVoiceInteraction(IBinder token) {
7058 synchronized(this) {
7059 ActivityRecord r = ActivityRecord.isInStackLocked(token);
7063 return r.rootVoiceInteraction;
7068 public IIntentSender getIntentSender(int type,
7069 String packageName, IBinder token, String resultWho,
7070 int requestCode, Intent[] intents, String[] resolvedTypes,
7071 int flags, Bundle bOptions, int userId) {
7072 enforceNotIsolatedCaller("getIntentSender");
7073 // Refuse possible leaked file descriptors
7074 if (intents != null) {
7075 if (intents.length < 1) {
7076 throw new IllegalArgumentException("Intents array length must be >= 1");
7078 for (int i=0; i<intents.length; i++) {
7079 Intent intent = intents[i];
7080 if (intent != null) {
7081 if (intent.hasFileDescriptors()) {
7082 throw new IllegalArgumentException("File descriptors passed in Intent");
7084 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7085 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7086 throw new IllegalArgumentException(
7087 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7089 intents[i] = new Intent(intent);
7092 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7093 throw new IllegalArgumentException(
7094 "Intent array length does not match resolvedTypes length");
7097 if (bOptions != null) {
7098 if (bOptions.hasFileDescriptors()) {
7099 throw new IllegalArgumentException("File descriptors passed in options");
7103 synchronized(this) {
7104 int callingUid = Binder.getCallingUid();
7105 int origUserId = userId;
7106 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7107 type == ActivityManager.INTENT_SENDER_BROADCAST,
7108 ALLOW_NON_FULL, "getIntentSender", null);
7109 if (origUserId == UserHandle.USER_CURRENT) {
7110 // We don't want to evaluate this until the pending intent is
7111 // actually executed. However, we do want to always do the
7112 // security checking for it above.
7113 userId = UserHandle.USER_CURRENT;
7116 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7117 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7118 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7119 if (!UserHandle.isSameApp(callingUid, uid)) {
7120 String msg = "Permission Denial: getIntentSender() from pid="
7121 + Binder.getCallingPid()
7122 + ", uid=" + Binder.getCallingUid()
7123 + ", (need uid=" + uid + ")"
7124 + " is not allowed to send as package " + packageName;
7126 throw new SecurityException(msg);
7130 return getIntentSenderLocked(type, packageName, callingUid, userId,
7131 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7133 } catch (RemoteException e) {
7134 throw new SecurityException(e);
7139 IIntentSender getIntentSenderLocked(int type, String packageName,
7140 int callingUid, int userId, IBinder token, String resultWho,
7141 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7143 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7144 ActivityRecord activity = null;
7145 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7146 activity = ActivityRecord.isInStackLocked(token);
7147 if (activity == null) {
7148 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7151 if (activity.finishing) {
7152 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7157 // We're going to be splicing together extras before sending, so we're
7158 // okay poking into any contained extras.
7159 if (intents != null) {
7160 for (int i = 0; i < intents.length; i++) {
7161 intents[i].setDefusable(true);
7164 Bundle.setDefusable(bOptions, true);
7166 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7167 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7168 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7169 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7170 |PendingIntent.FLAG_UPDATE_CURRENT);
7172 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7173 type, packageName, activity, resultWho,
7174 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7175 WeakReference<PendingIntentRecord> ref;
7176 ref = mIntentSenderRecords.get(key);
7177 PendingIntentRecord rec = ref != null ? ref.get() : null;
7179 if (!cancelCurrent) {
7180 if (updateCurrent) {
7181 if (rec.key.requestIntent != null) {
7182 rec.key.requestIntent.replaceExtras(intents != null ?
7183 intents[intents.length - 1] : null);
7185 if (intents != null) {
7186 intents[intents.length-1] = rec.key.requestIntent;
7187 rec.key.allIntents = intents;
7188 rec.key.allResolvedTypes = resolvedTypes;
7190 rec.key.allIntents = null;
7191 rec.key.allResolvedTypes = null;
7196 rec.canceled = true;
7197 mIntentSenderRecords.remove(key);
7202 rec = new PendingIntentRecord(this, key, callingUid);
7203 mIntentSenderRecords.put(key, rec.ref);
7204 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7205 if (activity.pendingResults == null) {
7206 activity.pendingResults
7207 = new HashSet<WeakReference<PendingIntentRecord>>();
7209 activity.pendingResults.add(rec.ref);
7215 public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7216 IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7217 if (target instanceof PendingIntentRecord) {
7218 return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7219 finishedReceiver, requiredPermission, options);
7221 if (intent == null) {
7222 // Weird case: someone has given us their own custom IIntentSender, and now
7223 // they have someone else trying to send to it but of course this isn't
7224 // really a PendingIntent, so there is no base Intent, and the caller isn't
7225 // supplying an Intent... but we never want to dispatch a null Intent to
7226 // a receiver, so um... let's make something up.
7227 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7228 intent = new Intent(Intent.ACTION_MAIN);
7231 target.send(code, intent, resolvedType, null, requiredPermission, options);
7232 } catch (RemoteException e) {
7234 // Platform code can rely on getting a result back when the send is done, but if
7235 // this intent sender is from outside of the system we can't rely on it doing that.
7236 // So instead we don't give it the result receiver, and instead just directly
7237 // report the finish immediately.
7238 if (finishedReceiver != null) {
7240 finishedReceiver.performReceive(intent, 0,
7241 null, null, false, false, UserHandle.getCallingUserId());
7242 } catch (RemoteException e) {
7250 * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7252 * <p>{@code callerUid} must be allowed to request such whitelist by calling
7253 * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7255 void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7256 if (DEBUG_WHITELISTS) {
7257 Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7258 + targetUid + ", " + duration + ")");
7260 synchronized (mPidsSelfLocked) {
7261 final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7263 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7266 if (!pr.whitelistManager) {
7267 if (DEBUG_WHITELISTS) {
7268 Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7269 + callerPid + " is not allowed");
7275 final long token = Binder.clearCallingIdentity();
7277 mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7278 true, "pe from uid:" + callerUid);
7280 Binder.restoreCallingIdentity(token);
7285 public void cancelIntentSender(IIntentSender sender) {
7286 if (!(sender instanceof PendingIntentRecord)) {
7289 synchronized(this) {
7290 PendingIntentRecord rec = (PendingIntentRecord)sender;
7292 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7293 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7294 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7295 String msg = "Permission Denial: cancelIntentSender() from pid="
7296 + Binder.getCallingPid()
7297 + ", uid=" + Binder.getCallingUid()
7298 + " is not allowed to cancel packges "
7299 + rec.key.packageName;
7301 throw new SecurityException(msg);
7303 } catch (RemoteException e) {
7304 throw new SecurityException(e);
7306 cancelIntentSenderLocked(rec, true);
7310 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7311 rec.canceled = true;
7312 mIntentSenderRecords.remove(rec.key);
7313 if (cleanActivity && rec.key.activity != null) {
7314 rec.key.activity.pendingResults.remove(rec.ref);
7319 public String getPackageForIntentSender(IIntentSender pendingResult) {
7320 if (!(pendingResult instanceof PendingIntentRecord)) {
7324 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7325 return res.key.packageName;
7326 } catch (ClassCastException e) {
7332 public int getUidForIntentSender(IIntentSender sender) {
7333 if (sender instanceof PendingIntentRecord) {
7335 PendingIntentRecord res = (PendingIntentRecord)sender;
7337 } catch (ClassCastException e) {
7344 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7345 if (!(pendingResult instanceof PendingIntentRecord)) {
7349 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7350 if (res.key.allIntents == null) {
7353 for (int i=0; i<res.key.allIntents.length; i++) {
7354 Intent intent = res.key.allIntents[i];
7355 if (intent.getPackage() != null && intent.getComponent() != null) {
7360 } catch (ClassCastException e) {
7366 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7367 if (!(pendingResult instanceof PendingIntentRecord)) {
7371 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7372 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7376 } catch (ClassCastException e) {
7382 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7383 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7384 "getIntentForIntentSender()");
7385 if (!(pendingResult instanceof PendingIntentRecord)) {
7389 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7390 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7391 } catch (ClassCastException e) {
7397 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7398 if (!(pendingResult instanceof PendingIntentRecord)) {
7402 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7403 synchronized (this) {
7404 return getTagForIntentSenderLocked(res, prefix);
7406 } catch (ClassCastException e) {
7411 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7412 final Intent intent = res.key.requestIntent;
7413 if (intent != null) {
7414 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7415 || res.lastTagPrefix.equals(prefix))) {
7418 res.lastTagPrefix = prefix;
7419 final StringBuilder sb = new StringBuilder(128);
7420 if (prefix != null) {
7423 if (intent.getAction() != null) {
7424 sb.append(intent.getAction());
7425 } else if (intent.getComponent() != null) {
7426 intent.getComponent().appendShortString(sb);
7430 return res.lastTag = sb.toString();
7436 public void setProcessLimit(int max) {
7437 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7438 "setProcessLimit()");
7439 synchronized (this) {
7440 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7441 mProcessLimitOverride = max;
7447 public int getProcessLimit() {
7448 synchronized (this) {
7449 return mProcessLimitOverride;
7453 void foregroundTokenDied(ForegroundToken token) {
7454 synchronized (ActivityManagerService.this) {
7455 synchronized (mPidsSelfLocked) {
7457 = mForegroundProcesses.get(token.pid);
7461 mForegroundProcesses.remove(token.pid);
7462 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7466 pr.forcingToForeground = null;
7467 updateProcessForegroundLocked(pr, false, false);
7469 updateOomAdjLocked();
7474 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7475 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7476 "setProcessForeground()");
7477 synchronized(this) {
7478 boolean changed = false;
7480 synchronized (mPidsSelfLocked) {
7481 ProcessRecord pr = mPidsSelfLocked.get(pid);
7482 if (pr == null && isForeground) {
7483 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7486 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7487 if (oldToken != null) {
7488 oldToken.token.unlinkToDeath(oldToken, 0);
7489 mForegroundProcesses.remove(pid);
7491 pr.forcingToForeground = null;
7495 if (isForeground && token != null) {
7496 ForegroundToken newToken = new ForegroundToken() {
7498 public void binderDied() {
7499 foregroundTokenDied(this);
7503 newToken.token = token;
7505 token.linkToDeath(newToken, 0);
7506 mForegroundProcesses.put(pid, newToken);
7507 pr.forcingToForeground = token;
7509 } catch (RemoteException e) {
7510 // If the process died while doing this, we will later
7511 // do the cleanup with the process death link.
7517 updateOomAdjLocked();
7523 public boolean isAppForeground(int uid) throws RemoteException {
7524 synchronized (this) {
7525 UidRecord uidRec = mActiveUids.get(uid);
7526 if (uidRec == null || uidRec.idle) {
7529 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7533 // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7534 // be guarded by permission checking.
7535 int getUidState(int uid) {
7536 synchronized (this) {
7537 UidRecord uidRec = mActiveUids.get(uid);
7538 return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7543 public boolean isInMultiWindowMode(IBinder token) {
7544 final long origId = Binder.clearCallingIdentity();
7546 synchronized(this) {
7547 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7551 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7552 return !r.task.mFullscreen;
7555 Binder.restoreCallingIdentity(origId);
7560 public boolean isInPictureInPictureMode(IBinder token) {
7561 final long origId = Binder.clearCallingIdentity();
7563 synchronized(this) {
7564 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7565 if (stack == null) {
7568 return stack.mStackId == PINNED_STACK_ID;
7571 Binder.restoreCallingIdentity(origId);
7576 public void enterPictureInPictureMode(IBinder token) {
7577 final long origId = Binder.clearCallingIdentity();
7579 synchronized(this) {
7580 if (!mSupportsPictureInPicture) {
7581 throw new IllegalStateException("enterPictureInPictureMode: "
7582 + "Device doesn't support picture-in-picture mode.");
7585 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7588 throw new IllegalStateException("enterPictureInPictureMode: "
7589 + "Can't find activity for token=" + token);
7592 if (!r.supportsPictureInPicture()) {
7593 throw new IllegalArgumentException("enterPictureInPictureMode: "
7594 + "Picture-In-Picture not supported for r=" + r);
7597 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7599 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7600 final Rect bounds = (pinnedStack != null)
7601 ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7603 mStackSupervisor.moveActivityToPinnedStackLocked(
7604 r, "enterPictureInPictureMode", bounds);
7607 Binder.restoreCallingIdentity(origId);
7611 // =========================================================
7613 // =========================================================
7615 static class ProcessInfoService extends IProcessInfoService.Stub {
7616 final ActivityManagerService mActivityManagerService;
7617 ProcessInfoService(ActivityManagerService activityManagerService) {
7618 mActivityManagerService = activityManagerService;
7622 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7623 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7624 /*in*/ pids, /*out*/ states, null);
7628 public void getProcessStatesAndOomScoresFromPids(
7629 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7630 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7631 /*in*/ pids, /*out*/ states, /*out*/ scores);
7636 * For each PID in the given input array, write the current process state
7637 * for that process into the states array, or -1 to indicate that no
7638 * process with the given PID exists. If scores array is provided, write
7639 * the oom score for the process into the scores array, with INVALID_ADJ
7640 * indicating the PID doesn't exist.
7642 public void getProcessStatesAndOomScoresForPIDs(
7643 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7644 if (scores != null) {
7645 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7646 "getProcessStatesAndOomScoresForPIDs()");
7650 throw new NullPointerException("pids");
7651 } else if (states == null) {
7652 throw new NullPointerException("states");
7653 } else if (pids.length != states.length) {
7654 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7655 } else if (scores != null && pids.length != scores.length) {
7656 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7659 synchronized (mPidsSelfLocked) {
7660 for (int i = 0; i < pids.length; i++) {
7661 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7662 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7664 if (scores != null) {
7665 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7671 // =========================================================
7673 // =========================================================
7675 static class PermissionController extends IPermissionController.Stub {
7676 ActivityManagerService mActivityManagerService;
7677 PermissionController(ActivityManagerService activityManagerService) {
7678 mActivityManagerService = activityManagerService;
7682 public boolean checkPermission(String permission, int pid, int uid) {
7683 return mActivityManagerService.checkPermission(permission, pid,
7684 uid) == PackageManager.PERMISSION_GRANTED;
7688 public String[] getPackagesForUid(int uid) {
7689 return mActivityManagerService.mContext.getPackageManager()
7690 .getPackagesForUid(uid);
7694 public boolean isRuntimePermission(String permission) {
7696 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7697 .getPermissionInfo(permission, 0);
7698 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7699 } catch (NameNotFoundException nnfe) {
7700 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7706 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7708 public int checkComponentPermission(String permission, int pid, int uid,
7709 int owningUid, boolean exported) {
7710 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7711 owningUid, exported);
7715 public Object getAMSLock() {
7716 return ActivityManagerService.this;
7721 * This can be called with or without the global lock held.
7723 int checkComponentPermission(String permission, int pid, int uid,
7724 int owningUid, boolean exported) {
7725 if (pid == MY_PID) {
7726 return PackageManager.PERMISSION_GRANTED;
7728 return ActivityManager.checkComponentPermission(permission, uid,
7729 owningUid, exported);
7733 * As the only public entry point for permissions checking, this method
7734 * can enforce the semantic that requesting a check on a null global
7735 * permission is automatically denied. (Internally a null permission
7736 * string is used when calling {@link #checkComponentPermission} in cases
7737 * when only uid-based security is needed.)
7739 * This can be called with or without the global lock held.
7742 public int checkPermission(String permission, int pid, int uid) {
7743 if (permission == null) {
7744 return PackageManager.PERMISSION_DENIED;
7746 return checkComponentPermission(permission, pid, uid, -1, true);
7750 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7751 if (permission == null) {
7752 return PackageManager.PERMISSION_DENIED;
7755 // We might be performing an operation on behalf of an indirect binder
7756 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7757 // client identity accordingly before proceeding.
7758 Identity tlsIdentity = sCallerIdentity.get();
7759 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7760 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7761 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7762 uid = tlsIdentity.uid;
7763 pid = tlsIdentity.pid;
7766 return checkComponentPermission(permission, pid, uid, -1, true);
7770 * Binder IPC calls go through the public entry point.
7771 * This can be called with or without the global lock held.
7773 int checkCallingPermission(String permission) {
7774 return checkPermission(permission,
7775 Binder.getCallingPid(),
7776 UserHandle.getAppId(Binder.getCallingUid()));
7780 * This can be called with or without the global lock held.
7782 void enforceCallingPermission(String permission, String func) {
7783 if (checkCallingPermission(permission)
7784 == PackageManager.PERMISSION_GRANTED) {
7788 String msg = "Permission Denial: " + func + " from pid="
7789 + Binder.getCallingPid()
7790 + ", uid=" + Binder.getCallingUid()
7791 + " requires " + permission;
7793 throw new SecurityException(msg);
7797 * Determine if UID is holding permissions required to access {@link Uri} in
7798 * the given {@link ProviderInfo}. Final permission checking is always done
7799 * in {@link ContentProvider}.
7801 private final boolean checkHoldingPermissionsLocked(
7802 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7803 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7804 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7805 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7806 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7807 != PERMISSION_GRANTED) {
7811 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7814 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7815 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7816 if (pi.applicationInfo.uid == uid) {
7818 } else if (!pi.exported) {
7822 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7823 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7825 // check if target holds top-level <provider> permissions
7826 if (!readMet && pi.readPermission != null && considerUidPermissions
7827 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7830 if (!writeMet && pi.writePermission != null && considerUidPermissions
7831 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7835 // track if unprotected read/write is allowed; any denied
7836 // <path-permission> below removes this ability
7837 boolean allowDefaultRead = pi.readPermission == null;
7838 boolean allowDefaultWrite = pi.writePermission == null;
7840 // check if target holds any <path-permission> that match uri
7841 final PathPermission[] pps = pi.pathPermissions;
7843 final String path = grantUri.uri.getPath();
7845 while (i > 0 && (!readMet || !writeMet)) {
7847 PathPermission pp = pps[i];
7848 if (pp.match(path)) {
7850 final String pprperm = pp.getReadPermission();
7851 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7852 "Checking read perm for " + pprperm + " for " + pp.getPath()
7853 + ": match=" + pp.match(path)
7854 + " check=" + pm.checkUidPermission(pprperm, uid));
7855 if (pprperm != null) {
7856 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7857 == PERMISSION_GRANTED) {
7860 allowDefaultRead = false;
7865 final String ppwperm = pp.getWritePermission();
7866 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7867 "Checking write perm " + ppwperm + " for " + pp.getPath()
7868 + ": match=" + pp.match(path)
7869 + " check=" + pm.checkUidPermission(ppwperm, uid));
7870 if (ppwperm != null) {
7871 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7872 == PERMISSION_GRANTED) {
7875 allowDefaultWrite = false;
7883 // grant unprotected <provider> read/write, if not blocked by
7884 // <path-permission> above
7885 if (allowDefaultRead) readMet = true;
7886 if (allowDefaultWrite) writeMet = true;
7888 } catch (RemoteException e) {
7892 return readMet && writeMet;
7895 public int getAppStartMode(int uid, String packageName) {
7896 synchronized (this) {
7897 return checkAllowBackgroundLocked(uid, packageName, -1, true);
7901 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7902 boolean allowWhenForeground) {
7903 UidRecord uidRec = mActiveUids.get(uid);
7904 if (!mLenientBackgroundCheck) {
7905 if (!allowWhenForeground || uidRec == null
7906 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7907 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7908 packageName) != AppOpsManager.MODE_ALLOWED) {
7909 return ActivityManager.APP_START_MODE_DELAYED;
7913 } else if (uidRec == null || uidRec.idle) {
7914 if (callingPid >= 0) {
7916 synchronized (mPidsSelfLocked) {
7917 proc = mPidsSelfLocked.get(callingPid);
7919 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7920 // Whoever is instigating this is in the foreground, so we will allow it
7922 return ActivityManager.APP_START_MODE_NORMAL;
7925 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7926 != AppOpsManager.MODE_ALLOWED) {
7927 return ActivityManager.APP_START_MODE_DELAYED;
7930 return ActivityManager.APP_START_MODE_NORMAL;
7933 private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7934 ProviderInfo pi = null;
7935 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7940 pi = AppGlobals.getPackageManager().resolveContentProvider(
7941 authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7943 } catch (RemoteException ex) {
7949 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7950 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7951 if (targetUris != null) {
7952 return targetUris.get(grantUri);
7957 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7958 String targetPkg, int targetUid, GrantUri grantUri) {
7959 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7960 if (targetUris == null) {
7961 targetUris = Maps.newArrayMap();
7962 mGrantedUriPermissions.put(targetUid, targetUris);
7965 UriPermission perm = targetUris.get(grantUri);
7967 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7968 targetUris.put(grantUri, perm);
7974 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7975 final int modeFlags) {
7976 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7977 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7978 : UriPermission.STRENGTH_OWNED;
7980 // Root gets to do everything.
7985 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7986 if (perms == null) return false;
7988 // First look for exact match
7989 final UriPermission exactPerm = perms.get(grantUri);
7990 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7994 // No exact match, look for prefixes
7995 final int N = perms.size();
7996 for (int i = 0; i < N; i++) {
7997 final UriPermission perm = perms.valueAt(i);
7998 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7999 && perm.getStrength(modeFlags) >= minStrength) {
8008 * @param uri This uri must NOT contain an embedded userId.
8009 * @param userId The userId in which the uri is to be resolved.
8012 public int checkUriPermission(Uri uri, int pid, int uid,
8013 final int modeFlags, int userId, IBinder callerToken) {
8014 enforceNotIsolatedCaller("checkUriPermission");
8016 // Another redirected-binder-call permissions check as in
8017 // {@link checkPermissionWithToken}.
8018 Identity tlsIdentity = sCallerIdentity.get();
8019 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8020 uid = tlsIdentity.uid;
8021 pid = tlsIdentity.pid;
8024 // Our own process gets to do everything.
8025 if (pid == MY_PID) {
8026 return PackageManager.PERMISSION_GRANTED;
8028 synchronized (this) {
8029 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8030 ? PackageManager.PERMISSION_GRANTED
8031 : PackageManager.PERMISSION_DENIED;
8036 * Check if the targetPkg can be granted permission to access uri by
8037 * the callingUid using the given modeFlags. Throws a security exception
8038 * if callingUid is not allowed to do this. Returns the uid of the target
8039 * if the URI permission grant should be performed; returns -1 if it is not
8040 * needed (for example targetPkg already has permission to access the URI).
8041 * If you already know the uid of the target, you can supply it in
8042 * lastTargetUid else set that to -1.
8044 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8045 final int modeFlags, int lastTargetUid) {
8046 if (!Intent.isAccessUriMode(modeFlags)) {
8050 if (targetPkg != null) {
8051 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8052 "Checking grant " + targetPkg + " permission to " + grantUri);
8055 final IPackageManager pm = AppGlobals.getPackageManager();
8057 // If this is not a content: uri, we can't do anything with it.
8058 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8059 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8060 "Can't grant URI permission for non-content URI: " + grantUri);
8064 final String authority = grantUri.uri.getAuthority();
8065 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8066 MATCH_DEBUG_TRIAGED_MISSING);
8068 Slog.w(TAG, "No content provider found for permission check: " +
8069 grantUri.uri.toSafeString());
8073 int targetUid = lastTargetUid;
8074 if (targetUid < 0 && targetPkg != null) {
8076 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8077 UserHandle.getUserId(callingUid));
8078 if (targetUid < 0) {
8079 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8080 "Can't grant URI permission no uid for: " + targetPkg);
8083 } catch (RemoteException ex) {
8088 if (targetUid >= 0) {
8089 // First... does the target actually need this permission?
8090 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8091 // No need to grant the target this permission.
8092 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8093 "Target " + targetPkg + " already has full permission to " + grantUri);
8097 // First... there is no target package, so can anyone access it?
8098 boolean allowed = pi.exported;
8099 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8100 if (pi.readPermission != null) {
8104 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8105 if (pi.writePermission != null) {
8114 /* There is a special cross user grant if:
8115 * - The target is on another user.
8116 * - Apps on the current user can access the uri without any uid permissions.
8117 * In this case, we grant a uri permission, even if the ContentProvider does not normally
8118 * grant uri permissions.
8120 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8121 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8122 modeFlags, false /*without considering the uid permissions*/);
8124 // Second... is the provider allowing granting of URI permissions?
8125 if (!specialCrossUserGrant) {
8126 if (!pi.grantUriPermissions) {
8127 throw new SecurityException("Provider " + pi.packageName
8129 + " does not allow granting of Uri permissions (uri "
8132 if (pi.uriPermissionPatterns != null) {
8133 final int N = pi.uriPermissionPatterns.length;
8134 boolean allowed = false;
8135 for (int i=0; i<N; i++) {
8136 if (pi.uriPermissionPatterns[i] != null
8137 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8143 throw new SecurityException("Provider " + pi.packageName
8145 + " does not allow granting of permission to path of Uri "
8151 // Third... does the caller itself have permission to access
8153 final int callingAppId = UserHandle.getAppId(callingUid);
8154 if ((callingAppId == Process.SYSTEM_UID) || (callingAppId == Process.ROOT_UID)) {
8155 Slog.w(TAG, "For security reasons, the system cannot issue a Uri permission"
8156 + " grant to " + grantUri + "; use startActivityAsCaller() instead");
8159 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8160 // Require they hold a strong enough Uri permission
8161 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8162 throw new SecurityException("Uid " + callingUid
8163 + " does not have permission to uri " + grantUri);
8171 * @param uri This uri must NOT contain an embedded userId.
8172 * @param userId The userId in which the uri is to be resolved.
8175 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8176 final int modeFlags, int userId) {
8177 enforceNotIsolatedCaller("checkGrantUriPermission");
8178 synchronized(this) {
8179 return checkGrantUriPermissionLocked(callingUid, targetPkg,
8180 new GrantUri(userId, uri, false), modeFlags, -1);
8184 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8185 final int modeFlags, UriPermissionOwner owner) {
8186 if (!Intent.isAccessUriMode(modeFlags)) {
8190 // So here we are: the caller has the assumed permission
8191 // to the uri, and the target doesn't. Let's now give this to
8194 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8195 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8197 final String authority = grantUri.uri.getAuthority();
8198 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8199 MATCH_DEBUG_TRIAGED_MISSING);
8201 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8205 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8206 grantUri.prefix = true;
8208 final UriPermission perm = findOrCreateUriPermissionLocked(
8209 pi.packageName, targetPkg, targetUid, grantUri);
8210 perm.grantModes(modeFlags, owner);
8213 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8214 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8215 if (targetPkg == null) {
8216 throw new NullPointerException("targetPkg");
8219 final IPackageManager pm = AppGlobals.getPackageManager();
8221 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8222 } catch (RemoteException ex) {
8226 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8228 if (targetUid < 0) {
8232 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8236 static class NeededUriGrants extends ArrayList<GrantUri> {
8237 final String targetPkg;
8238 final int targetUid;
8241 NeededUriGrants(String targetPkg, int targetUid, int flags) {
8242 this.targetPkg = targetPkg;
8243 this.targetUid = targetUid;
8249 * Like checkGrantUriPermissionLocked, but takes an Intent.
8251 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8252 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8253 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8254 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8255 + " clip=" + (intent != null ? intent.getClipData() : null)
8256 + " from " + intent + "; flags=0x"
8257 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8259 if (targetPkg == null) {
8260 throw new NullPointerException("targetPkg");
8263 if (intent == null) {
8266 Uri data = intent.getData();
8267 ClipData clip = intent.getClipData();
8268 if (data == null && clip == null) {
8271 // Default userId for uris in the intent (if they don't specify it themselves)
8272 int contentUserHint = intent.getContentUserHint();
8273 if (contentUserHint == UserHandle.USER_CURRENT) {
8274 contentUserHint = UserHandle.getUserId(callingUid);
8276 final IPackageManager pm = AppGlobals.getPackageManager();
8278 if (needed != null) {
8279 targetUid = needed.targetUid;
8282 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8284 } catch (RemoteException ex) {
8287 if (targetUid < 0) {
8288 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8289 "Can't grant URI permission no uid for: " + targetPkg
8290 + " on user " + targetUserId);
8295 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8296 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8298 if (targetUid > 0) {
8299 if (needed == null) {
8300 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8302 needed.add(grantUri);
8306 for (int i=0; i<clip.getItemCount(); i++) {
8307 Uri uri = clip.getItemAt(i).getUri();
8309 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8310 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8312 if (targetUid > 0) {
8313 if (needed == null) {
8314 needed = new NeededUriGrants(targetPkg, targetUid, mode);
8316 needed.add(grantUri);
8319 Intent clipIntent = clip.getItemAt(i).getIntent();
8320 if (clipIntent != null) {
8321 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8322 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8323 if (newNeeded != null) {
8335 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8337 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8338 UriPermissionOwner owner) {
8339 if (needed != null) {
8340 for (int i=0; i<needed.size(); i++) {
8341 GrantUri grantUri = needed.get(i);
8342 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8343 grantUri, needed.flags, owner);
8348 void grantUriPermissionFromIntentLocked(int callingUid,
8349 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8350 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8351 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8352 if (needed == null) {
8356 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8360 * @param uri This uri must NOT contain an embedded userId.
8361 * @param userId The userId in which the uri is to be resolved.
8364 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8365 final int modeFlags, int userId) {
8366 enforceNotIsolatedCaller("grantUriPermission");
8367 GrantUri grantUri = new GrantUri(userId, uri, false);
8368 synchronized(this) {
8369 final ProcessRecord r = getRecordForAppLocked(caller);
8371 throw new SecurityException("Unable to find app for caller "
8373 + " when granting permission to uri " + grantUri);
8375 if (targetPkg == null) {
8376 throw new IllegalArgumentException("null target");
8378 if (grantUri == null) {
8379 throw new IllegalArgumentException("null uri");
8382 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8383 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8384 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8385 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8387 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8388 UserHandle.getUserId(r.uid));
8392 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8393 if (perm.modeFlags == 0) {
8394 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8396 if (perms != null) {
8397 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8398 "Removing " + perm.targetUid + " permission to " + perm.uri);
8400 perms.remove(perm.uri);
8401 if (perms.isEmpty()) {
8402 mGrantedUriPermissions.remove(perm.targetUid);
8408 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8409 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8410 "Revoking all granted permissions to " + grantUri);
8412 final IPackageManager pm = AppGlobals.getPackageManager();
8413 final String authority = grantUri.uri.getAuthority();
8414 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8415 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8417 Slog.w(TAG, "No content provider found for permission revoke: "
8418 + grantUri.toSafeString());
8422 // Does the caller have this permission on the URI?
8423 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8424 // If they don't have direct access to the URI, then revoke any
8425 // ownerless URI permissions that have been granted to them.
8426 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8427 if (perms != null) {
8428 boolean persistChanged = false;
8429 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8430 final UriPermission perm = it.next();
8431 if (perm.uri.sourceUserId == grantUri.sourceUserId
8432 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8433 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8434 "Revoking non-owned " + perm.targetUid
8435 + " permission to " + perm.uri);
8436 persistChanged |= perm.revokeModes(
8437 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8438 if (perm.modeFlags == 0) {
8443 if (perms.isEmpty()) {
8444 mGrantedUriPermissions.remove(callingUid);
8446 if (persistChanged) {
8447 schedulePersistUriGrants();
8453 boolean persistChanged = false;
8455 // Go through all of the permissions and remove any that match.
8456 int N = mGrantedUriPermissions.size();
8457 for (int i = 0; i < N; i++) {
8458 final int targetUid = mGrantedUriPermissions.keyAt(i);
8459 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8461 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8462 final UriPermission perm = it.next();
8463 if (perm.uri.sourceUserId == grantUri.sourceUserId
8464 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8465 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8466 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8467 persistChanged |= perm.revokeModes(
8468 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8469 if (perm.modeFlags == 0) {
8475 if (perms.isEmpty()) {
8476 mGrantedUriPermissions.remove(targetUid);
8482 if (persistChanged) {
8483 schedulePersistUriGrants();
8488 * @param uri This uri must NOT contain an embedded userId.
8489 * @param userId The userId in which the uri is to be resolved.
8492 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8494 enforceNotIsolatedCaller("revokeUriPermission");
8495 synchronized(this) {
8496 final ProcessRecord r = getRecordForAppLocked(caller);
8498 throw new SecurityException("Unable to find app for caller "
8500 + " when revoking permission to uri " + uri);
8503 Slog.w(TAG, "revokeUriPermission: null uri");
8507 if (!Intent.isAccessUriMode(modeFlags)) {
8511 final String authority = uri.getAuthority();
8512 final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8513 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8515 Slog.w(TAG, "No content provider found for permission revoke: "
8516 + uri.toSafeString());
8520 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8525 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8528 * @param packageName Package name to match, or {@code null} to apply to all
8530 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8532 * @param persistable If persistable grants should be removed.
8534 private void removeUriPermissionsForPackageLocked(
8535 String packageName, int userHandle, boolean persistable) {
8536 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8537 throw new IllegalArgumentException("Must narrow by either package or user");
8540 boolean persistChanged = false;
8542 int N = mGrantedUriPermissions.size();
8543 for (int i = 0; i < N; i++) {
8544 final int targetUid = mGrantedUriPermissions.keyAt(i);
8545 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8547 // Only inspect grants matching user
8548 if (userHandle == UserHandle.USER_ALL
8549 || userHandle == UserHandle.getUserId(targetUid)) {
8550 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8551 final UriPermission perm = it.next();
8553 // Only inspect grants matching package
8554 if (packageName == null || perm.sourcePkg.equals(packageName)
8555 || perm.targetPkg.equals(packageName)) {
8556 // Hacky solution as part of fixing a security bug; ignore
8557 // grants associated with DownloadManager so we don't have
8558 // to immediately launch it to regrant the permissions
8559 if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8560 && !persistable) continue;
8562 persistChanged |= perm.revokeModes(persistable
8563 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8565 // Only remove when no modes remain; any persisted grants
8566 // will keep this alive.
8567 if (perm.modeFlags == 0) {
8573 if (perms.isEmpty()) {
8574 mGrantedUriPermissions.remove(targetUid);
8581 if (persistChanged) {
8582 schedulePersistUriGrants();
8587 public IBinder newUriPermissionOwner(String name) {
8588 enforceNotIsolatedCaller("newUriPermissionOwner");
8589 synchronized(this) {
8590 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8591 return owner.getExternalTokenLocked();
8596 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8597 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8598 synchronized(this) {
8599 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8601 throw new IllegalArgumentException("Activity does not exist; token="
8604 return r.getUriPermissionsLocked().getExternalTokenLocked();
8608 * @param uri This uri must NOT contain an embedded userId.
8609 * @param sourceUserId The userId in which the uri is to be resolved.
8610 * @param targetUserId The userId of the app that receives the grant.
8613 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8614 final int modeFlags, int sourceUserId, int targetUserId) {
8615 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8616 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8617 "grantUriPermissionFromOwner", null);
8618 synchronized(this) {
8619 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8620 if (owner == null) {
8621 throw new IllegalArgumentException("Unknown owner: " + token);
8623 if (fromUid != Binder.getCallingUid()) {
8624 if (Binder.getCallingUid() != Process.myUid()) {
8625 // Only system code can grant URI permissions on behalf
8627 throw new SecurityException("nice try");
8630 if (targetPkg == null) {
8631 throw new IllegalArgumentException("null target");
8634 throw new IllegalArgumentException("null uri");
8637 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8638 modeFlags, owner, targetUserId);
8643 * @param uri This uri must NOT contain an embedded userId.
8644 * @param userId The userId in which the uri is to be resolved.
8647 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8648 synchronized(this) {
8649 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8650 if (owner == null) {
8651 throw new IllegalArgumentException("Unknown owner: " + token);
8655 owner.removeUriPermissionsLocked(mode);
8657 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8658 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8663 private void schedulePersistUriGrants() {
8664 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8665 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8666 10 * DateUtils.SECOND_IN_MILLIS);
8670 private void writeGrantedUriPermissions() {
8671 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8673 // Snapshot permissions so we can persist without lock
8674 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8675 synchronized (this) {
8676 final int size = mGrantedUriPermissions.size();
8677 for (int i = 0; i < size; i++) {
8678 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8679 for (UriPermission perm : perms.values()) {
8680 if (perm.persistedModeFlags != 0) {
8681 persist.add(perm.snapshot());
8687 FileOutputStream fos = null;
8689 fos = mGrantFile.startWrite();
8691 XmlSerializer out = new FastXmlSerializer();
8692 out.setOutput(fos, StandardCharsets.UTF_8.name());
8693 out.startDocument(null, true);
8694 out.startTag(null, TAG_URI_GRANTS);
8695 for (UriPermission.Snapshot perm : persist) {
8696 out.startTag(null, TAG_URI_GRANT);
8697 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8698 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8699 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8700 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8701 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8702 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8703 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8704 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8705 out.endTag(null, TAG_URI_GRANT);
8707 out.endTag(null, TAG_URI_GRANTS);
8710 mGrantFile.finishWrite(fos);
8711 } catch (IOException e) {
8713 mGrantFile.failWrite(fos);
8718 private void readGrantedUriPermissionsLocked() {
8719 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8721 final long now = System.currentTimeMillis();
8723 FileInputStream fis = null;
8725 fis = mGrantFile.openRead();
8726 final XmlPullParser in = Xml.newPullParser();
8727 in.setInput(fis, StandardCharsets.UTF_8.name());
8730 while ((type = in.next()) != END_DOCUMENT) {
8731 final String tag = in.getName();
8732 if (type == START_TAG) {
8733 if (TAG_URI_GRANT.equals(tag)) {
8734 final int sourceUserId;
8735 final int targetUserId;
8736 final int userHandle = readIntAttribute(in,
8737 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8738 if (userHandle != UserHandle.USER_NULL) {
8739 // For backwards compatibility.
8740 sourceUserId = userHandle;
8741 targetUserId = userHandle;
8743 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8744 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8746 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8747 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8748 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8749 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8750 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8751 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8753 // Sanity check that provider still belongs to source package
8754 // Both direct boot aware and unaware packages are fine as we
8755 // will do filtering at query time to avoid multiple parsing.
8756 final ProviderInfo pi = getProviderInfoLocked(
8757 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8758 | MATCH_DIRECT_BOOT_UNAWARE);
8759 if (pi != null && sourcePkg.equals(pi.packageName)) {
8762 targetUid = AppGlobals.getPackageManager().getPackageUid(
8763 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8764 } catch (RemoteException e) {
8766 if (targetUid != -1) {
8767 final UriPermission perm = findOrCreateUriPermissionLocked(
8768 sourcePkg, targetPkg, targetUid,
8769 new GrantUri(sourceUserId, uri, prefix));
8770 perm.initPersistedModes(modeFlags, createdTime);
8773 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8774 + " but instead found " + pi);
8779 } catch (FileNotFoundException e) {
8780 // Missing grants is okay
8781 } catch (IOException e) {
8782 Slog.wtf(TAG, "Failed reading Uri grants", e);
8783 } catch (XmlPullParserException e) {
8784 Slog.wtf(TAG, "Failed reading Uri grants", e);
8786 IoUtils.closeQuietly(fis);
8791 * @param uri This uri must NOT contain an embedded userId.
8792 * @param userId The userId in which the uri is to be resolved.
8795 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8796 enforceNotIsolatedCaller("takePersistableUriPermission");
8798 Preconditions.checkFlagsArgument(modeFlags,
8799 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8801 synchronized (this) {
8802 final int callingUid = Binder.getCallingUid();
8803 boolean persistChanged = false;
8804 GrantUri grantUri = new GrantUri(userId, uri, false);
8806 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8807 new GrantUri(userId, uri, false));
8808 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8809 new GrantUri(userId, uri, true));
8811 final boolean exactValid = (exactPerm != null)
8812 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8813 final boolean prefixValid = (prefixPerm != null)
8814 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8816 if (!(exactValid || prefixValid)) {
8817 throw new SecurityException("No persistable permission grants found for UID "
8818 + callingUid + " and Uri " + grantUri.toSafeString());
8822 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8825 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8828 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8830 if (persistChanged) {
8831 schedulePersistUriGrants();
8837 * @param uri This uri must NOT contain an embedded userId.
8838 * @param userId The userId in which the uri is to be resolved.
8841 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8842 enforceNotIsolatedCaller("releasePersistableUriPermission");
8844 Preconditions.checkFlagsArgument(modeFlags,
8845 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8847 synchronized (this) {
8848 final int callingUid = Binder.getCallingUid();
8849 boolean persistChanged = false;
8851 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8852 new GrantUri(userId, uri, false));
8853 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8854 new GrantUri(userId, uri, true));
8855 if (exactPerm == null && prefixPerm == null) {
8856 throw new SecurityException("No permission grants found for UID " + callingUid
8857 + " and Uri " + uri.toSafeString());
8860 if (exactPerm != null) {
8861 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8862 removeUriPermissionIfNeededLocked(exactPerm);
8864 if (prefixPerm != null) {
8865 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8866 removeUriPermissionIfNeededLocked(prefixPerm);
8869 if (persistChanged) {
8870 schedulePersistUriGrants();
8876 * Prune any older {@link UriPermission} for the given UID until outstanding
8877 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8879 * @return if any mutations occured that require persisting.
8881 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8882 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8883 if (perms == null) return false;
8884 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8886 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8887 for (UriPermission perm : perms.values()) {
8888 if (perm.persistedModeFlags != 0) {
8889 persisted.add(perm);
8893 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8894 if (trimCount <= 0) return false;
8896 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8897 for (int i = 0; i < trimCount; i++) {
8898 final UriPermission perm = persisted.get(i);
8900 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8901 "Trimming grant created at " + perm.persistedCreateTime);
8903 perm.releasePersistableModes(~0);
8904 removeUriPermissionIfNeededLocked(perm);
8911 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8912 String packageName, boolean incoming) {
8913 enforceNotIsolatedCaller("getPersistedUriPermissions");
8914 Preconditions.checkNotNull(packageName, "packageName");
8916 final int callingUid = Binder.getCallingUid();
8917 final int callingUserId = UserHandle.getUserId(callingUid);
8918 final IPackageManager pm = AppGlobals.getPackageManager();
8920 final int packageUid = pm.getPackageUid(packageName,
8921 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8922 if (packageUid != callingUid) {
8923 throw new SecurityException(
8924 "Package " + packageName + " does not belong to calling UID " + callingUid);
8926 } catch (RemoteException e) {
8927 throw new SecurityException("Failed to verify package name ownership");
8930 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8931 synchronized (this) {
8933 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8935 if (perms == null) {
8936 Slog.w(TAG, "No permission grants found for " + packageName);
8938 for (UriPermission perm : perms.values()) {
8939 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8940 result.add(perm.buildPersistedPublicApiObject());
8945 final int size = mGrantedUriPermissions.size();
8946 for (int i = 0; i < size; i++) {
8947 final ArrayMap<GrantUri, UriPermission> perms =
8948 mGrantedUriPermissions.valueAt(i);
8949 for (UriPermission perm : perms.values()) {
8950 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8951 result.add(perm.buildPersistedPublicApiObject());
8957 return new ParceledListSlice<android.content.UriPermission>(result);
8961 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8962 String packageName, int userId) {
8963 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8964 "getGrantedUriPermissions");
8966 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8967 synchronized (this) {
8968 final int size = mGrantedUriPermissions.size();
8969 for (int i = 0; i < size; i++) {
8970 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8971 for (UriPermission perm : perms.values()) {
8972 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8973 && perm.persistedModeFlags != 0) {
8974 result.add(perm.buildPersistedPublicApiObject());
8979 return new ParceledListSlice<android.content.UriPermission>(result);
8983 public void clearGrantedUriPermissions(String packageName, int userId) {
8984 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8985 "clearGrantedUriPermissions");
8986 removeUriPermissionsForPackageLocked(packageName, userId, true);
8990 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8991 synchronized (this) {
8993 who != null ? getRecordForAppLocked(who) : null;
8994 if (app == null) return;
8996 Message msg = Message.obtain();
8997 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8999 msg.arg1 = waiting ? 1 : 0;
9000 mUiHandler.sendMessage(msg);
9005 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9006 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9007 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9008 outInfo.availMem = Process.getFreeMemory();
9009 outInfo.totalMem = Process.getTotalMemory();
9010 outInfo.threshold = homeAppMem;
9011 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9012 outInfo.hiddenAppThreshold = cachedAppMem;
9013 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9014 ProcessList.SERVICE_ADJ);
9015 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9016 ProcessList.VISIBLE_APP_ADJ);
9017 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9018 ProcessList.FOREGROUND_APP_ADJ);
9021 // =========================================================
9023 // =========================================================
9026 public List<IAppTask> getAppTasks(String callingPackage) {
9027 int callingUid = Binder.getCallingUid();
9028 long ident = Binder.clearCallingIdentity();
9030 synchronized(this) {
9031 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9033 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9035 final int N = mRecentTasks.size();
9036 for (int i = 0; i < N; i++) {
9037 TaskRecord tr = mRecentTasks.get(i);
9038 // Skip tasks that do not match the caller. We don't need to verify
9039 // callingPackage, because we are also limiting to callingUid and know
9040 // that will limit to the correct security sandbox.
9041 if (tr.effectiveUid != callingUid) {
9044 Intent intent = tr.getBaseIntent();
9045 if (intent == null ||
9046 !callingPackage.equals(intent.getComponent().getPackageName())) {
9049 ActivityManager.RecentTaskInfo taskInfo =
9050 createRecentTaskInfoFromTaskRecord(tr);
9051 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9055 Binder.restoreCallingIdentity(ident);
9062 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9063 final int callingUid = Binder.getCallingUid();
9064 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9066 synchronized(this) {
9067 if (DEBUG_ALL) Slog.v(
9068 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9070 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9073 // TODO: Improve with MRU list from all ActivityStacks.
9074 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9081 * Creates a new RecentTaskInfo from a TaskRecord.
9083 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9084 // Update the task description to reflect any changes in the task stack
9085 tr.updateTaskDescription();
9087 // Compose the recent task info
9088 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9089 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9090 rti.persistentId = tr.taskId;
9091 rti.baseIntent = new Intent(tr.getBaseIntent());
9092 rti.origActivity = tr.origActivity;
9093 rti.realActivity = tr.realActivity;
9094 rti.description = tr.lastDescription;
9095 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9096 rti.userId = tr.userId;
9097 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9098 rti.firstActiveTime = tr.firstActiveTime;
9099 rti.lastActiveTime = tr.lastActiveTime;
9100 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9101 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9102 rti.numActivities = 0;
9103 if (tr.mBounds != null) {
9104 rti.bounds = new Rect(tr.mBounds);
9106 rti.isDockable = tr.canGoInDockedStack();
9107 rti.resizeMode = tr.mResizeMode;
9109 ActivityRecord base = null;
9110 ActivityRecord top = null;
9113 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9114 tmp = tr.mActivities.get(i);
9115 if (tmp.finishing) {
9119 if (top == null || (top.state == ActivityState.INITIALIZING)) {
9122 rti.numActivities++;
9125 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9126 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9131 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9132 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9133 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9135 if (checkPermission(android.Manifest.permission.GET_TASKS,
9136 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9137 // Temporary compatibility: some existing apps on the system image may
9138 // still be requesting the old permission and not switched to the new
9139 // one; if so, we'll still allow them full access. This means we need
9140 // to see if they are holding the old permission and are a system app.
9142 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9144 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9145 + " is using old GET_TASKS but privileged; allowing");
9147 } catch (RemoteException e) {
9152 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9153 + " does not hold REAL_GET_TASKS; limiting output");
9159 public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9161 final int callingUid = Binder.getCallingUid();
9162 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9163 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9165 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9166 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9167 synchronized (this) {
9168 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9170 final boolean detailed = checkCallingPermission(
9171 android.Manifest.permission.GET_DETAILED_TASKS)
9172 == PackageManager.PERMISSION_GRANTED;
9174 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9175 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9176 return ParceledListSlice.emptyList();
9178 mRecentTasks.loadUserRecentsLocked(userId);
9180 final int recentsCount = mRecentTasks.size();
9181 ArrayList<ActivityManager.RecentTaskInfo> res =
9182 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9184 final Set<Integer> includedUsers;
9185 if (includeProfiles) {
9186 includedUsers = mUserController.getProfileIds(userId);
9188 includedUsers = new HashSet<>();
9190 includedUsers.add(Integer.valueOf(userId));
9192 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9193 TaskRecord tr = mRecentTasks.get(i);
9194 // Only add calling user or related users recent tasks
9195 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9196 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9200 if (tr.realActivitySuspended) {
9201 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9205 // Return the entry if desired by the caller. We always return
9206 // the first entry, because callers always expect this to be the
9207 // foreground app. We may filter others if the caller has
9208 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9209 // we should exclude the entry.
9213 || (tr.intent == null)
9214 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9217 // If the caller doesn't have the GET_TASKS permission, then only
9218 // allow them to see a small subset of tasks -- their own and home.
9219 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9220 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9224 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9225 if (tr.stack != null && tr.stack.isHomeStack()) {
9226 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9227 "Skipping, home stack task: " + tr);
9231 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9232 final ActivityStack stack = tr.stack;
9233 if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9234 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9235 "Skipping, top task in docked stack: " + tr);
9239 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9240 if (tr.stack != null && tr.stack.isPinnedStack()) {
9241 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9242 "Skipping, pinned stack task: " + tr);
9246 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9247 // Don't include auto remove tasks that are finished or finishing.
9248 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9249 "Skipping, auto-remove without activity: " + tr);
9252 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9253 && !tr.isAvailable) {
9254 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9255 "Skipping, unavail real act: " + tr);
9259 if (!tr.mUserSetupComplete) {
9260 // Don't include task launched while user is not done setting-up.
9261 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9262 "Skipping, user setup not complete: " + tr);
9266 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9268 rti.baseIntent.replaceExtras((Bundle)null);
9275 return new ParceledListSlice<>(res);
9280 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9281 synchronized (this) {
9282 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9283 "getTaskThumbnail()");
9284 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9285 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9287 return tr.getTaskThumbnailLocked();
9294 public int addAppTask(IBinder activityToken, Intent intent,
9295 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9296 final int callingUid = Binder.getCallingUid();
9297 final long callingIdent = Binder.clearCallingIdentity();
9300 synchronized (this) {
9301 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9303 throw new IllegalArgumentException("Activity does not exist; token="
9306 ComponentName comp = intent.getComponent();
9308 throw new IllegalArgumentException("Intent " + intent
9309 + " must specify explicit component");
9311 if (thumbnail.getWidth() != mThumbnailWidth
9312 || thumbnail.getHeight() != mThumbnailHeight) {
9313 throw new IllegalArgumentException("Bad thumbnail size: got "
9314 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9315 + mThumbnailWidth + "x" + mThumbnailHeight);
9317 if (intent.getSelector() != null) {
9318 intent.setSelector(null);
9320 if (intent.getSourceBounds() != null) {
9321 intent.setSourceBounds(null);
9323 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9324 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9325 // The caller has added this as an auto-remove task... that makes no
9326 // sense, so turn off auto-remove.
9327 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9330 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9331 mLastAddedTaskActivity = null;
9333 ActivityInfo ainfo = mLastAddedTaskActivity;
9334 if (ainfo == null) {
9335 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9336 comp, 0, UserHandle.getUserId(callingUid));
9337 if (ainfo.applicationInfo.uid != callingUid) {
9338 throw new SecurityException(
9339 "Can't add task for another application: target uid="
9340 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9344 // Use the full screen as the context for the task thumbnail
9345 final Point displaySize = new Point();
9346 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9347 r.task.stack.getDisplaySize(displaySize);
9348 thumbnailInfo.taskWidth = displaySize.x;
9349 thumbnailInfo.taskHeight = displaySize.y;
9350 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9352 TaskRecord task = new TaskRecord(this,
9353 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9354 ainfo, intent, description, thumbnailInfo);
9356 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9358 // If this would have caused a trim, then we'll abort because that
9359 // means it would be added at the end of the list but then just removed.
9360 return INVALID_TASK_ID;
9363 final int N = mRecentTasks.size();
9364 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9365 final TaskRecord tr = mRecentTasks.remove(N - 1);
9366 tr.removedFromRecents();
9369 task.inRecents = true;
9370 mRecentTasks.add(task);
9371 r.task.stack.addTask(task, false, "addAppTask");
9373 task.setLastThumbnailLocked(thumbnail);
9374 task.freeLastThumbnail();
9379 Binder.restoreCallingIdentity(callingIdent);
9384 public Point getAppTaskThumbnailSize() {
9385 synchronized (this) {
9386 return new Point(mThumbnailWidth, mThumbnailHeight);
9391 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9392 synchronized (this) {
9393 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9395 r.setTaskDescription(td);
9396 r.task.updateTaskDescription();
9402 public void setTaskResizeable(int taskId, int resizeableMode) {
9403 synchronized (this) {
9404 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9405 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9407 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9410 if (task.mResizeMode != resizeableMode) {
9411 task.mResizeMode = resizeableMode;
9412 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9413 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9414 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9420 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9421 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9422 long ident = Binder.clearCallingIdentity();
9424 synchronized (this) {
9425 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9427 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9430 int stackId = task.stack.mStackId;
9431 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9432 // in crop windows resize mode or if the task size is affected by the docked stack
9433 // changing size. No need to update configuration.
9434 if (bounds != null && task.inCropWindowsResizeMode()
9435 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9436 mWindowManager.scrollTask(task.taskId, bounds);
9440 // Place the task in the right stack if it isn't there already based on
9441 // the requested bounds.
9442 // The stack transition logic is:
9443 // - a null bounds on a freeform task moves that task to fullscreen
9444 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9445 // that task to freeform
9446 // - otherwise the task is not moved
9447 if (!StackId.isTaskResizeAllowed(stackId)) {
9448 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9450 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9451 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9452 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9453 stackId = FREEFORM_WORKSPACE_STACK_ID;
9455 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9456 if (stackId != task.stack.mStackId) {
9457 mStackSupervisor.moveTaskToStackUncheckedLocked(
9458 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9459 preserveWindow = false;
9462 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9463 false /* deferResume */);
9466 Binder.restoreCallingIdentity(ident);
9471 public Rect getTaskBounds(int taskId) {
9472 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9473 long ident = Binder.clearCallingIdentity();
9474 Rect rect = new Rect();
9476 synchronized (this) {
9477 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9478 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9480 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9483 if (task.stack != null) {
9484 // Return the bounds from window manager since it will be adjusted for various
9485 // things like the presense of a docked stack for tasks that aren't resizeable.
9486 mWindowManager.getTaskBounds(task.taskId, rect);
9488 // Task isn't in window manager yet since it isn't associated with a stack.
9489 // Return the persist value from activity manager
9490 if (task.mBounds != null) {
9491 rect.set(task.mBounds);
9492 } else if (task.mLastNonFullscreenBounds != null) {
9493 rect.set(task.mLastNonFullscreenBounds);
9498 Binder.restoreCallingIdentity(ident);
9504 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9505 if (userId != UserHandle.getCallingUserId()) {
9506 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9507 "getTaskDescriptionIcon");
9509 final File passedIconFile = new File(filePath);
9510 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9511 passedIconFile.getName());
9512 if (!legitIconFile.getPath().equals(filePath)
9513 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9514 throw new IllegalArgumentException("Bad file path: " + filePath
9515 + " passed for userId " + userId);
9517 return mRecentTasks.getTaskDescriptionIcon(filePath);
9521 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9522 throws RemoteException {
9523 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9524 opts.getCustomInPlaceResId() == 0) {
9525 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9526 "with valid animation");
9528 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9529 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9530 opts.getCustomInPlaceResId());
9531 mWindowManager.executeAppTransition();
9534 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9535 boolean removeFromRecents) {
9536 if (removeFromRecents) {
9537 mRecentTasks.remove(tr);
9538 tr.removedFromRecents();
9540 ComponentName component = tr.getBaseIntent().getComponent();
9541 if (component == null) {
9542 Slog.w(TAG, "No component for base intent of task: " + tr);
9546 // Find any running services associated with this app and stop if needed.
9547 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9553 // Determine if the process(es) for this task should be killed.
9554 final String pkg = component.getPackageName();
9555 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9556 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9557 for (int i = 0; i < pmap.size(); i++) {
9559 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9560 for (int j = 0; j < uids.size(); j++) {
9561 ProcessRecord proc = uids.valueAt(j);
9562 if (proc.userId != tr.userId) {
9563 // Don't kill process for a different user.
9566 if (proc == mHomeProcess) {
9567 // Don't kill the home process along with tasks from the same package.
9570 if (!proc.pkgList.containsKey(pkg)) {
9571 // Don't kill process that is not associated with this task.
9575 for (int k = 0; k < proc.activities.size(); k++) {
9576 TaskRecord otherTask = proc.activities.get(k).task;
9577 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9578 // Don't kill process(es) that has an activity in a different task that is
9584 if (proc.foregroundServices) {
9585 // Don't kill process(es) with foreground service.
9589 // Add process to kill list.
9590 procsToKill.add(proc);
9594 // Kill the running processes.
9595 for (int i = 0; i < procsToKill.size(); i++) {
9596 ProcessRecord pr = procsToKill.get(i);
9597 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9598 && pr.curReceiver == null) {
9599 pr.kill("remove task", true);
9601 // We delay killing processes that are not in the background or running a receiver.
9602 pr.waitingToKill = "remove task";
9607 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9608 // Remove all tasks with activities in the specified package from the list of recent tasks
9609 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9610 TaskRecord tr = mRecentTasks.get(i);
9611 if (tr.userId != userId) continue;
9613 ComponentName cn = tr.intent.getComponent();
9614 if (cn != null && cn.getPackageName().equals(packageName)) {
9615 // If the package name matches, remove the task.
9616 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9621 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9624 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9625 TaskRecord tr = mRecentTasks.get(i);
9626 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9630 ComponentName cn = tr.intent.getComponent();
9631 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9632 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9633 if (sameComponent) {
9634 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9640 * Removes the task with the specified task id.
9642 * @param taskId Identifier of the task to be removed.
9643 * @param killProcess Kill any process associated with the task if possible.
9644 * @param removeFromRecents Whether to also remove the task from recents.
9645 * @return Returns true if the given task was found and removed.
9647 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9648 boolean removeFromRecents) {
9649 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9650 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9652 tr.removeTaskActivitiesLocked();
9653 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9654 if (tr.isPersistable) {
9655 notifyTaskPersisterLocked(null, true);
9659 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9664 public void removeStack(int stackId) {
9665 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9666 if (stackId == HOME_STACK_ID) {
9667 throw new IllegalArgumentException("Removing home stack is not allowed.");
9670 synchronized (this) {
9671 final long ident = Binder.clearCallingIdentity();
9673 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9674 if (stack == null) {
9677 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9678 for (int i = tasks.size() - 1; i >= 0; i--) {
9679 removeTaskByIdLocked(
9680 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9683 Binder.restoreCallingIdentity(ident);
9689 public boolean removeTask(int taskId) {
9690 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9691 synchronized (this) {
9692 final long ident = Binder.clearCallingIdentity();
9694 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9696 Binder.restoreCallingIdentity(ident);
9702 * TODO: Add mController hook
9705 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9706 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9708 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9709 synchronized(this) {
9710 moveTaskToFrontLocked(taskId, flags, bOptions);
9714 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9715 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9717 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9718 Binder.getCallingUid(), -1, -1, "Task to front")) {
9719 ActivityOptions.abort(options);
9722 final long origId = Binder.clearCallingIdentity();
9724 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9726 Slog.d(TAG, "Could not find task for id: "+ taskId);
9729 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9730 mStackSupervisor.showLockTaskToast();
9731 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9734 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9735 if (prev != null && prev.isRecentsActivity()) {
9736 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9738 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9739 false /* forceNonResizable */);
9741 Binder.restoreCallingIdentity(origId);
9743 ActivityOptions.abort(options);
9747 * Moves an activity, and all of the other activities within the same task, to the bottom
9748 * of the history stack. The activity's order within the task is unchanged.
9750 * @param token A reference to the activity we wish to move
9751 * @param nonRoot If false then this only works if the activity is the root
9752 * of a task; if true it will work for any activity in a task.
9753 * @return Returns true if the move completed, false if not.
9756 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9757 enforceNotIsolatedCaller("moveActivityTaskToBack");
9758 synchronized(this) {
9759 final long origId = Binder.clearCallingIdentity();
9761 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9762 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9764 if (mStackSupervisor.isLockedTask(task)) {
9765 mStackSupervisor.showLockTaskToast();
9768 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9771 Binder.restoreCallingIdentity(origId);
9778 public void moveTaskBackwards(int task) {
9779 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9780 "moveTaskBackwards()");
9782 synchronized(this) {
9783 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9784 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9787 final long origId = Binder.clearCallingIdentity();
9788 moveTaskBackwardsLocked(task);
9789 Binder.restoreCallingIdentity(origId);
9793 private final void moveTaskBackwardsLocked(int task) {
9794 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9798 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9799 IActivityContainerCallback callback) throws RemoteException {
9800 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9801 synchronized (this) {
9802 if (parentActivityToken == null) {
9803 throw new IllegalArgumentException("parent token must not be null");
9805 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9809 if (callback == null) {
9810 throw new IllegalArgumentException("callback must not be null");
9812 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9817 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9818 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9819 synchronized (this) {
9820 mStackSupervisor.deleteActivityContainer(container);
9825 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9826 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9827 synchronized (this) {
9828 final int stackId = mStackSupervisor.getNextStackId();
9829 final ActivityStack stack =
9830 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9831 if (stack == null) {
9834 return stack.mActivityContainer;
9839 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9840 synchronized (this) {
9841 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9842 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9843 return stack.mActivityContainer.getDisplayId();
9845 return Display.DEFAULT_DISPLAY;
9850 public int getActivityStackId(IBinder token) throws RemoteException {
9851 synchronized (this) {
9852 ActivityStack stack = ActivityRecord.getStackLocked(token);
9853 if (stack == null) {
9854 return INVALID_STACK_ID;
9856 return stack.mStackId;
9861 public void exitFreeformMode(IBinder token) throws RemoteException {
9862 synchronized (this) {
9863 long ident = Binder.clearCallingIdentity();
9865 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9867 throw new IllegalArgumentException(
9868 "exitFreeformMode: No activity record matching token=" + token);
9870 final ActivityStack stack = r.getStackLocked(token);
9871 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9872 throw new IllegalStateException(
9873 "exitFreeformMode: You can only go fullscreen from freeform.");
9875 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9876 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9877 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9879 Binder.restoreCallingIdentity(ident);
9885 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9886 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9887 if (stackId == HOME_STACK_ID) {
9888 throw new IllegalArgumentException(
9889 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9891 synchronized (this) {
9892 long ident = Binder.clearCallingIdentity();
9894 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9895 + " to stackId=" + stackId + " toTop=" + toTop);
9896 if (stackId == DOCKED_STACK_ID) {
9897 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9898 null /* initialBounds */);
9900 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9901 !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9902 if (result && stackId == DOCKED_STACK_ID) {
9903 // If task moved to docked stack - show recents if needed.
9904 mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9905 "moveTaskToDockedStack");
9908 Binder.restoreCallingIdentity(ident);
9914 public void swapDockedAndFullscreenStack() throws RemoteException {
9915 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9916 synchronized (this) {
9917 long ident = Binder.clearCallingIdentity();
9919 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9920 FULLSCREEN_WORKSPACE_STACK_ID);
9921 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9923 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9924 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9926 if (topTask == null || tasks == null || tasks.size() == 0) {
9928 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9932 // TODO: App transition
9933 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9935 // Defer the resume so resume/pausing while moving stacks is dangerous.
9936 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9937 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9938 ANIMATE, true /* deferResume */);
9939 final int size = tasks.size();
9940 for (int i = 0; i < size; i++) {
9941 final int id = tasks.get(i).taskId;
9942 if (id == topTask.taskId) {
9945 mStackSupervisor.moveTaskToStackLocked(id,
9946 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9947 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9950 // Because we deferred the resume, to avoid conflicts with stack switches while
9951 // resuming, we need to do it after all the tasks are moved.
9952 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9953 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9955 mWindowManager.executeAppTransition();
9957 Binder.restoreCallingIdentity(ident);
9963 * Moves the input task to the docked stack.
9965 * @param taskId Id of task to move.
9966 * @param createMode The mode the docked stack should be created in if it doesn't exist
9968 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9970 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9971 * @param toTop If the task and stack should be moved to the top.
9972 * @param animate Whether we should play an animation for the moving the task
9973 * @param initialBounds If the docked stack gets created, it will use these bounds for the
9974 * docked stack. Pass {@code null} to use default bounds.
9977 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9978 Rect initialBounds, boolean moveHomeStackFront) {
9979 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9980 synchronized (this) {
9981 long ident = Binder.clearCallingIdentity();
9983 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9984 + " to createMode=" + createMode + " toTop=" + toTop);
9985 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9986 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9987 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9988 animate, DEFER_RESUME);
9990 if (moveHomeStackFront) {
9991 mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9993 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9997 Binder.restoreCallingIdentity(ident);
10003 * Moves the top activity in the input stackId to the pinned stack.
10005 * @param stackId Id of stack to move the top activity to pinned stack.
10006 * @param bounds Bounds to use for pinned stack.
10008 * @return True if the top activity of the input stack was successfully moved to the pinned
10012 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10013 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10014 synchronized (this) {
10015 if (!mSupportsPictureInPicture) {
10016 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10017 + "Device doesn't support picture-in-pciture mode");
10020 long ident = Binder.clearCallingIdentity();
10022 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10024 Binder.restoreCallingIdentity(ident);
10030 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10031 boolean preserveWindows, boolean animate, int animationDuration) {
10032 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10033 long ident = Binder.clearCallingIdentity();
10035 synchronized (this) {
10037 if (stackId == PINNED_STACK_ID) {
10038 mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10040 throw new IllegalArgumentException("Stack: " + stackId
10041 + " doesn't support animated resize.");
10044 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10045 null /* tempTaskInsetBounds */, preserveWindows,
10046 allowResizeInDockedMode, !DEFER_RESUME);
10050 Binder.restoreCallingIdentity(ident);
10055 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10056 Rect tempDockedTaskInsetBounds,
10057 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10058 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10059 "resizeDockedStack()");
10060 long ident = Binder.clearCallingIdentity();
10062 synchronized (this) {
10063 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10064 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10068 Binder.restoreCallingIdentity(ident);
10073 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10074 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10075 "resizePinnedStack()");
10076 final long ident = Binder.clearCallingIdentity();
10078 synchronized (this) {
10079 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10082 Binder.restoreCallingIdentity(ident);
10087 public void positionTaskInStack(int taskId, int stackId, int position) {
10088 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10089 if (stackId == HOME_STACK_ID) {
10090 throw new IllegalArgumentException(
10091 "positionTaskInStack: Attempt to change the position of task "
10092 + taskId + " in/to home stack");
10094 synchronized (this) {
10095 long ident = Binder.clearCallingIdentity();
10097 if (DEBUG_STACK) Slog.d(TAG_STACK,
10098 "positionTaskInStack: positioning task=" + taskId
10099 + " in stackId=" + stackId + " at position=" + position);
10100 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10102 Binder.restoreCallingIdentity(ident);
10108 public List<StackInfo> getAllStackInfos() {
10109 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10110 long ident = Binder.clearCallingIdentity();
10112 synchronized (this) {
10113 return mStackSupervisor.getAllStackInfosLocked();
10116 Binder.restoreCallingIdentity(ident);
10121 public StackInfo getStackInfo(int stackId) {
10122 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10123 long ident = Binder.clearCallingIdentity();
10125 synchronized (this) {
10126 return mStackSupervisor.getStackInfoLocked(stackId);
10129 Binder.restoreCallingIdentity(ident);
10134 public boolean isInHomeStack(int taskId) {
10135 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10136 long ident = Binder.clearCallingIdentity();
10138 synchronized (this) {
10139 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10140 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10141 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10144 Binder.restoreCallingIdentity(ident);
10149 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10150 synchronized(this) {
10151 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10156 public void updateDeviceOwner(String packageName) {
10157 final int callingUid = Binder.getCallingUid();
10158 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10159 throw new SecurityException("updateDeviceOwner called from non-system process");
10161 synchronized (this) {
10162 mDeviceOwnerName = packageName;
10167 public void updateLockTaskPackages(int userId, String[] packages) {
10168 final int callingUid = Binder.getCallingUid();
10169 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10170 enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10171 "updateLockTaskPackages()");
10173 synchronized (this) {
10174 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10175 Arrays.toString(packages));
10176 mLockTaskPackages.put(userId, packages);
10177 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10182 void startLockTaskModeLocked(TaskRecord task) {
10183 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10184 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10188 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10189 // is initiated by system after the pinning request was shown and locked mode is initiated
10190 // by an authorized app directly
10191 final int callingUid = Binder.getCallingUid();
10192 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10193 long ident = Binder.clearCallingIdentity();
10195 if (!isSystemInitiated) {
10196 task.mLockTaskUid = callingUid;
10197 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10198 // startLockTask() called by app and task mode is lockTaskModeDefault.
10199 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10200 StatusBarManagerInternal statusBarManager =
10201 LocalServices.getService(StatusBarManagerInternal.class);
10202 if (statusBarManager != null) {
10203 statusBarManager.showScreenPinningRequest(task.taskId);
10208 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10209 if (stack == null || task != stack.topTask()) {
10210 throw new IllegalArgumentException("Invalid task, not in foreground");
10213 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10215 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10216 ActivityManager.LOCK_TASK_MODE_PINNED :
10217 ActivityManager.LOCK_TASK_MODE_LOCKED,
10218 "startLockTask", true);
10220 Binder.restoreCallingIdentity(ident);
10225 public void startLockTaskMode(int taskId) {
10226 synchronized (this) {
10227 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10228 if (task != null) {
10229 startLockTaskModeLocked(task);
10235 public void startLockTaskMode(IBinder token) {
10236 synchronized (this) {
10237 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10241 final TaskRecord task = r.task;
10242 if (task != null) {
10243 startLockTaskModeLocked(task);
10249 public void startSystemLockTaskMode(int taskId) throws RemoteException {
10250 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10251 // This makes inner call to look as if it was initiated by system.
10252 long ident = Binder.clearCallingIdentity();
10254 synchronized (this) {
10255 startLockTaskMode(taskId);
10258 Binder.restoreCallingIdentity(ident);
10263 public void stopLockTaskMode() {
10264 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10265 if (lockTask == null) {
10266 // Our work here is done.
10270 final int callingUid = Binder.getCallingUid();
10271 final int lockTaskUid = lockTask.mLockTaskUid;
10272 final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10273 if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10277 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10278 // It is possible lockTaskMode was started by the system process because
10279 // android:lockTaskMode is set to a locking value in the application manifest
10280 // instead of the app calling startLockTaskMode. In this case
10281 // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10282 // {@link TaskRecord.effectiveUid} instead. Also caller with
10283 // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10284 if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10285 && callingUid != lockTaskUid
10286 && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10287 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10288 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10291 long ident = Binder.clearCallingIdentity();
10293 Log.d(TAG, "stopLockTaskMode");
10295 synchronized (this) {
10296 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10297 "stopLockTask", true);
10299 TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10301 tm.showInCallScreen(false);
10304 Binder.restoreCallingIdentity(ident);
10309 * This API should be called by SystemUI only when user perform certain action to dismiss
10310 * lock task mode. We should only dismiss pinned lock task mode in this case.
10313 public void stopSystemLockTaskMode() throws RemoteException {
10314 if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10315 stopLockTaskMode();
10317 mStackSupervisor.showLockTaskToast();
10322 public boolean isInLockTaskMode() {
10323 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10327 public int getLockTaskModeState() {
10328 synchronized (this) {
10329 return mStackSupervisor.getLockTaskModeState();
10334 public void showLockTaskEscapeMessage(IBinder token) {
10335 synchronized (this) {
10336 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10340 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10344 // =========================================================
10345 // CONTENT PROVIDERS
10346 // =========================================================
10348 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10349 List<ProviderInfo> providers = null;
10351 providers = AppGlobals.getPackageManager()
10352 .queryContentProviders(app.processName, app.uid,
10353 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10354 | MATCH_DEBUG_TRIAGED_MISSING)
10356 } catch (RemoteException ex) {
10358 if (DEBUG_MU) Slog.v(TAG_MU,
10359 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10360 int userId = app.userId;
10361 if (providers != null) {
10362 int N = providers.size();
10363 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10364 for (int i=0; i<N; i++) {
10365 // TODO: keep logic in sync with installEncryptionUnawareProviders
10367 (ProviderInfo)providers.get(i);
10368 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10369 cpi.name, cpi.flags);
10370 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10371 // This is a singleton provider, but a user besides the
10372 // default user is asking to initialize a process it runs
10373 // in... well, no, it doesn't actually run in this process,
10374 // it runs in the process of the default user. Get rid of it.
10375 providers.remove(i);
10381 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10382 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10384 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10385 mProviderMap.putProviderByClass(comp, cpr);
10387 if (DEBUG_MU) Slog.v(TAG_MU,
10388 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10389 app.pubProviders.put(cpi.name, cpr);
10390 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10391 // Don't add this if it is a platform component that is marked
10392 // to run in multiple processes, because this is actually
10393 // part of the framework so doesn't make sense to track as a
10394 // separate apk in the process.
10395 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10398 notifyPackageUse(cpi.applicationInfo.packageName,
10399 PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10406 * Check if the calling UID has a possible chance at accessing the provider
10407 * at the given authority and user.
10409 public String checkContentProviderAccess(String authority, int userId) {
10410 if (userId == UserHandle.USER_ALL) {
10411 mContext.enforceCallingOrSelfPermission(
10412 Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10413 userId = UserHandle.getCallingUserId();
10416 ProviderInfo cpi = null;
10418 cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10419 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10420 | PackageManager.MATCH_DIRECT_BOOT_AWARE
10421 | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10423 } catch (RemoteException ignored) {
10426 // TODO: make this an outright failure in a future platform release;
10427 // until then anonymous content notifications are unprotected
10428 //return "Failed to find provider " + authority + " for user " + userId;
10432 ProcessRecord r = null;
10433 synchronized (mPidsSelfLocked) {
10434 r = mPidsSelfLocked.get(Binder.getCallingPid());
10437 return "Failed to find PID " + Binder.getCallingPid();
10440 synchronized (this) {
10441 return checkContentProviderPermissionLocked(cpi, r, userId, true);
10446 * Check if {@link ProcessRecord} has a possible chance at accessing the
10447 * given {@link ProviderInfo}. Final permission checking is always done
10448 * in {@link ContentProvider}.
10450 private final String checkContentProviderPermissionLocked(
10451 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10452 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10453 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10454 boolean checkedGrants = false;
10456 // Looking for cross-user grants before enforcing the typical cross-users permissions
10457 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10458 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10459 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10462 checkedGrants = true;
10464 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10465 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10466 if (userId != tmpTargetUserId) {
10467 // When we actually went to determine the final targer user ID, this ended
10468 // up different than our initial check for the authority. This is because
10469 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10470 // SELF. So we need to re-check the grants again.
10471 checkedGrants = false;
10474 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10475 cpi.applicationInfo.uid, cpi.exported)
10476 == PackageManager.PERMISSION_GRANTED) {
10479 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10480 cpi.applicationInfo.uid, cpi.exported)
10481 == PackageManager.PERMISSION_GRANTED) {
10485 PathPermission[] pps = cpi.pathPermissions;
10487 int i = pps.length;
10490 PathPermission pp = pps[i];
10491 String pprperm = pp.getReadPermission();
10492 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10493 cpi.applicationInfo.uid, cpi.exported)
10494 == PackageManager.PERMISSION_GRANTED) {
10497 String ppwperm = pp.getWritePermission();
10498 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10499 cpi.applicationInfo.uid, cpi.exported)
10500 == PackageManager.PERMISSION_GRANTED) {
10505 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10510 if (!cpi.exported) {
10511 msg = "Permission Denial: opening provider " + cpi.name
10512 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10513 + ", uid=" + callingUid + ") that is not exported from uid "
10514 + cpi.applicationInfo.uid;
10516 msg = "Permission Denial: opening provider " + cpi.name
10517 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10518 + ", uid=" + callingUid + ") requires "
10519 + cpi.readPermission + " or " + cpi.writePermission;
10526 * Returns if the ContentProvider has granted a uri to callingUid
10528 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10529 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10530 if (perms != null) {
10531 for (int i=perms.size()-1; i>=0; i--) {
10532 GrantUri grantUri = perms.keyAt(i);
10533 if (grantUri.sourceUserId == userId || !checkUser) {
10534 if (matchesProvider(grantUri.uri, cpi)) {
10544 * Returns true if the uri authority is one of the authorities specified in the provider.
10546 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10547 String uriAuth = uri.getAuthority();
10548 String cpiAuth = cpi.authority;
10549 if (cpiAuth.indexOf(';') == -1) {
10550 return cpiAuth.equals(uriAuth);
10552 String[] cpiAuths = cpiAuth.split(";");
10553 int length = cpiAuths.length;
10554 for (int i = 0; i < length; i++) {
10555 if (cpiAuths[i].equals(uriAuth)) return true;
10560 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10561 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10563 for (int i=0; i<r.conProviders.size(); i++) {
10564 ContentProviderConnection conn = r.conProviders.get(i);
10565 if (conn.provider == cpr) {
10566 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10567 "Adding provider requested by "
10568 + r.processName + " from process "
10569 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10570 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10572 conn.stableCount++;
10573 conn.numStableIncs++;
10575 conn.unstableCount++;
10576 conn.numUnstableIncs++;
10581 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10583 conn.stableCount = 1;
10584 conn.numStableIncs = 1;
10586 conn.unstableCount = 1;
10587 conn.numUnstableIncs = 1;
10589 cpr.connections.add(conn);
10590 r.conProviders.add(conn);
10591 startAssociationLocked(r.uid, r.processName, r.curProcState,
10592 cpr.uid, cpr.name, cpr.info.processName);
10595 cpr.addExternalProcessHandleLocked(externalProcessToken);
10599 boolean decProviderCountLocked(ContentProviderConnection conn,
10600 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10601 if (conn != null) {
10602 cpr = conn.provider;
10603 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10604 "Removing provider requested by "
10605 + conn.client.processName + " from process "
10606 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10607 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10609 conn.stableCount--;
10611 conn.unstableCount--;
10613 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10614 cpr.connections.remove(conn);
10615 conn.client.conProviders.remove(conn);
10616 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10617 // The client is more important than last activity -- note the time this
10618 // is happening, so we keep the old provider process around a bit as last
10619 // activity to avoid thrashing it.
10620 if (cpr.proc != null) {
10621 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10624 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10629 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10633 private void checkTime(long startTime, String where) {
10634 long now = SystemClock.uptimeMillis();
10635 if ((now-startTime) > 50) {
10636 // If we are taking more than 50ms, log about it.
10637 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10641 private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10643 PROC_SPACE_TERM|PROC_PARENS,
10644 PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG, // 3: process state
10647 private final long[] mProcessStateStatsLongs = new long[1];
10649 boolean isProcessAliveLocked(ProcessRecord proc) {
10650 if (proc.procStatFile == null) {
10651 proc.procStatFile = "/proc/" + proc.pid + "/stat";
10653 mProcessStateStatsLongs[0] = 0;
10654 if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10655 mProcessStateStatsLongs, null)) {
10656 if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10659 final long state = mProcessStateStatsLongs[0];
10660 if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10662 return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10665 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10666 String name, IBinder token, boolean stable, int userId) {
10667 ContentProviderRecord cpr;
10668 ContentProviderConnection conn = null;
10669 ProviderInfo cpi = null;
10671 synchronized(this) {
10672 long startTime = SystemClock.uptimeMillis();
10674 ProcessRecord r = null;
10675 if (caller != null) {
10676 r = getRecordForAppLocked(caller);
10678 throw new SecurityException(
10679 "Unable to find app for caller " + caller
10680 + " (pid=" + Binder.getCallingPid()
10681 + ") when getting content provider " + name);
10685 boolean checkCrossUser = true;
10687 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10689 // First check if this content provider has been published...
10690 cpr = mProviderMap.getProviderByName(name, userId);
10691 // If that didn't work, check if it exists for user 0 and then
10692 // verify that it's a singleton provider before using it.
10693 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10694 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10697 if (isSingleton(cpi.processName, cpi.applicationInfo,
10698 cpi.name, cpi.flags)
10699 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10700 userId = UserHandle.USER_SYSTEM;
10701 checkCrossUser = false;
10709 boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10710 if (providerRunning) {
10713 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10714 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10716 throw new SecurityException(msg);
10718 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10720 if (r != null && cpr.canRunHere(r)) {
10721 // This provider has been published or is in the process
10722 // of being published... but it is also allowed to run
10723 // in the caller's process, so don't make a connection
10724 // and just let the caller instantiate its own instance.
10725 ContentProviderHolder holder = cpr.newHolder(null);
10726 // don't give caller the provider object, it needs
10727 // to make its own.
10728 holder.provider = null;
10732 final long origId = Binder.clearCallingIdentity();
10734 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10736 // In this case the provider instance already exists, so we can
10737 // return it right away.
10738 conn = incProviderCountLocked(r, cpr, token, stable);
10739 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10740 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10741 // If this is a perceptible app accessing the provider,
10742 // make sure to count it as being accessed and thus
10743 // back up on the LRU list. This is good because
10744 // content providers are often expensive to start.
10745 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10746 updateLruProcessLocked(cpr.proc, false, null);
10747 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10751 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10752 final int verifiedAdj = cpr.proc.verifiedAdj;
10753 boolean success = updateOomAdjLocked(cpr.proc);
10754 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10755 // if the process has been successfully adjusted. So to reduce races with
10756 // it, we will check whether the process still exists. Note that this doesn't
10757 // completely get rid of races with LMK killing the process, but should make
10758 // them much smaller.
10759 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10762 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10763 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10764 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10765 // NOTE: there is still a race here where a signal could be
10766 // pending on the process even though we managed to update its
10767 // adj level. Not sure what to do about this, but at least
10768 // the race is now smaller.
10770 // Uh oh... it looks like the provider's process
10771 // has been killed on us. We need to wait for a new
10772 // process to be started, and make sure its death
10773 // doesn't kill our process.
10774 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10775 + " is crashing; detaching " + r);
10776 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10777 checkTime(startTime, "getContentProviderImpl: before appDied");
10778 appDiedLocked(cpr.proc);
10779 checkTime(startTime, "getContentProviderImpl: after appDied");
10781 // This wasn't the last ref our process had on
10782 // the provider... we have now been killed, bail.
10785 providerRunning = false;
10788 cpr.proc.verifiedAdj = cpr.proc.setAdj;
10791 Binder.restoreCallingIdentity(origId);
10794 if (!providerRunning) {
10796 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10797 cpi = AppGlobals.getPackageManager().
10798 resolveContentProvider(name,
10799 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10800 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10801 } catch (RemoteException ex) {
10806 // If the provider is a singleton AND
10807 // (it's a call within the same user || the provider is a
10809 // Then allow connecting to the singleton provider
10810 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10811 cpi.name, cpi.flags)
10812 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10814 userId = UserHandle.USER_SYSTEM;
10816 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10817 checkTime(startTime, "getContentProviderImpl: got app info for user");
10820 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10821 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10823 throw new SecurityException(msg);
10825 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10827 if (!mProcessesReady
10828 && !cpi.processName.equals("system")) {
10829 // If this content provider does not run in the system
10830 // process, and the system is not yet ready to run other
10831 // processes, then fail fast instead of hanging.
10832 throw new IllegalArgumentException(
10833 "Attempt to launch content provider before system ready");
10836 // Make sure that the user who owns this provider is running. If not,
10837 // we don't want to allow it to run.
10838 if (!mUserController.isUserRunningLocked(userId, 0)) {
10839 Slog.w(TAG, "Unable to launch app "
10840 + cpi.applicationInfo.packageName + "/"
10841 + cpi.applicationInfo.uid + " for provider "
10842 + name + ": user " + userId + " is stopped");
10846 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10847 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10848 cpr = mProviderMap.getProviderByClass(comp, userId);
10849 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10850 final boolean firstClass = cpr == null;
10852 final long ident = Binder.clearCallingIdentity();
10854 // If permissions need a review before any of the app components can run,
10855 // we return no provider and launch a review activity if the calling app
10856 // is in the foreground.
10857 if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10858 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10864 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10865 ApplicationInfo ai =
10866 AppGlobals.getPackageManager().
10867 getApplicationInfo(
10868 cpi.applicationInfo.packageName,
10869 STOCK_PM_FLAGS, userId);
10870 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10872 Slog.w(TAG, "No package info for content provider "
10876 ai = getAppInfoForUser(ai, userId);
10877 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10878 } catch (RemoteException ex) {
10879 // pm is in same process, this will never happen.
10881 Binder.restoreCallingIdentity(ident);
10885 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10887 if (r != null && cpr.canRunHere(r)) {
10888 // If this is a multiprocess provider, then just return its
10889 // info and allow the caller to instantiate it. Only do
10890 // this if the provider is the same user as the caller's
10891 // process, or can run as root (so can be in any process).
10892 return cpr.newHolder(null);
10895 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10896 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10897 + cpr.info.name + " callers=" + Debug.getCallers(6));
10899 // This is single process, and our app is now connecting to it.
10900 // See if we are already in the process of launching this
10902 final int N = mLaunchingProviders.size();
10904 for (i = 0; i < N; i++) {
10905 if (mLaunchingProviders.get(i) == cpr) {
10910 // If the provider is not already being launched, then get it
10913 final long origId = Binder.clearCallingIdentity();
10916 // Content provider is now in use, its package can't be stopped.
10918 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10919 AppGlobals.getPackageManager().setPackageStoppedState(
10920 cpr.appInfo.packageName, false, userId);
10921 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10922 } catch (RemoteException e) {
10923 } catch (IllegalArgumentException e) {
10924 Slog.w(TAG, "Failed trying to unstop package "
10925 + cpr.appInfo.packageName + ": " + e);
10928 // Use existing process if already started
10929 checkTime(startTime, "getContentProviderImpl: looking for process record");
10930 ProcessRecord proc = getProcessRecordLocked(
10931 cpi.processName, cpr.appInfo.uid, false);
10932 if (proc != null && proc.thread != null && !proc.killed) {
10933 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10934 "Installing in existing process " + proc);
10935 if (!proc.pubProviders.containsKey(cpi.name)) {
10936 checkTime(startTime, "getContentProviderImpl: scheduling install");
10937 proc.pubProviders.put(cpi.name, cpr);
10939 proc.thread.scheduleInstallProvider(cpi);
10940 } catch (RemoteException e) {
10944 checkTime(startTime, "getContentProviderImpl: before start process");
10945 proc = startProcessLocked(cpi.processName,
10946 cpr.appInfo, false, 0, "content provider",
10947 new ComponentName(cpi.applicationInfo.packageName,
10948 cpi.name), false, false, false);
10949 checkTime(startTime, "getContentProviderImpl: after start process");
10950 if (proc == null) {
10951 Slog.w(TAG, "Unable to launch app "
10952 + cpi.applicationInfo.packageName + "/"
10953 + cpi.applicationInfo.uid + " for provider "
10954 + name + ": process is bad");
10958 cpr.launchingApp = proc;
10959 mLaunchingProviders.add(cpr);
10961 Binder.restoreCallingIdentity(origId);
10965 checkTime(startTime, "getContentProviderImpl: updating data structures");
10967 // Make sure the provider is published (the same provider class
10968 // may be published under multiple names).
10970 mProviderMap.putProviderByClass(comp, cpr);
10973 mProviderMap.putProviderByName(name, cpr);
10974 conn = incProviderCountLocked(r, cpr, token, stable);
10975 if (conn != null) {
10976 conn.waiting = true;
10979 checkTime(startTime, "getContentProviderImpl: done!");
10982 // Wait for the provider to be published...
10983 synchronized (cpr) {
10984 while (cpr.provider == null) {
10985 if (cpr.launchingApp == null) {
10986 Slog.w(TAG, "Unable to launch app "
10987 + cpi.applicationInfo.packageName + "/"
10988 + cpi.applicationInfo.uid + " for provider "
10989 + name + ": launching app became null");
10990 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10991 UserHandle.getUserId(cpi.applicationInfo.uid),
10992 cpi.applicationInfo.packageName,
10993 cpi.applicationInfo.uid, name);
10997 if (DEBUG_MU) Slog.v(TAG_MU,
10998 "Waiting to start provider " + cpr
10999 + " launchingApp=" + cpr.launchingApp);
11000 if (conn != null) {
11001 conn.waiting = true;
11004 } catch (InterruptedException ex) {
11006 if (conn != null) {
11007 conn.waiting = false;
11012 return cpr != null ? cpr.newHolder(conn) : null;
11015 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11016 ProcessRecord r, final int userId) {
11017 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11018 cpi.packageName, userId)) {
11020 final boolean callerForeground = r == null || r.setSchedGroup
11021 != ProcessList.SCHED_GROUP_BACKGROUND;
11023 // Show a permission review UI only for starting from a foreground app
11024 if (!callerForeground) {
11025 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11026 + cpi.packageName + " requires a permissions review");
11030 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11031 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11032 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11033 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11035 if (DEBUG_PERMISSIONS_REVIEW) {
11036 Slog.i(TAG, "u" + userId + " Launching permission review "
11037 + "for package " + cpi.packageName);
11040 final UserHandle userHandle = new UserHandle(userId);
11041 mHandler.post(new Runnable() {
11043 public void run() {
11044 mContext.startActivityAsUser(intent, userHandle);
11054 PackageManagerInternal getPackageManagerInternalLocked() {
11055 if (mPackageManagerInt == null) {
11056 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11058 return mPackageManagerInt;
11062 public final ContentProviderHolder getContentProvider(
11063 IApplicationThread caller, String name, int userId, boolean stable) {
11064 enforceNotIsolatedCaller("getContentProvider");
11065 if (caller == null) {
11066 String msg = "null IApplicationThread when getting content provider "
11069 throw new SecurityException(msg);
11071 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11072 // with cross-user grant.
11073 return getContentProviderImpl(caller, name, null, stable, userId);
11076 public ContentProviderHolder getContentProviderExternal(
11077 String name, int userId, IBinder token) {
11078 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11079 "Do not have permission in call getContentProviderExternal()");
11080 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11081 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11082 return getContentProviderExternalUnchecked(name, token, userId);
11085 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11086 IBinder token, int userId) {
11087 return getContentProviderImpl(null, name, token, true, userId);
11091 * Drop a content provider from a ProcessRecord's bookkeeping
11093 public void removeContentProvider(IBinder connection, boolean stable) {
11094 enforceNotIsolatedCaller("removeContentProvider");
11095 long ident = Binder.clearCallingIdentity();
11097 synchronized (this) {
11098 ContentProviderConnection conn;
11100 conn = (ContentProviderConnection)connection;
11101 } catch (ClassCastException e) {
11102 String msg ="removeContentProvider: " + connection
11103 + " not a ContentProviderConnection";
11105 throw new IllegalArgumentException(msg);
11107 if (conn == null) {
11108 throw new NullPointerException("connection is null");
11110 if (decProviderCountLocked(conn, null, null, stable)) {
11111 updateOomAdjLocked();
11115 Binder.restoreCallingIdentity(ident);
11119 public void removeContentProviderExternal(String name, IBinder token) {
11120 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11121 "Do not have permission in call removeContentProviderExternal()");
11122 int userId = UserHandle.getCallingUserId();
11123 long ident = Binder.clearCallingIdentity();
11125 removeContentProviderExternalUnchecked(name, token, userId);
11127 Binder.restoreCallingIdentity(ident);
11131 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11132 synchronized (this) {
11133 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11135 //remove from mProvidersByClass
11136 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11140 //update content provider record entry info
11141 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11142 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11143 if (localCpr.hasExternalProcessHandles()) {
11144 if (localCpr.removeExternalProcessHandleLocked(token)) {
11145 updateOomAdjLocked();
11147 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11148 + " with no external reference for token: "
11152 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11153 + " with no external references.");
11158 public final void publishContentProviders(IApplicationThread caller,
11159 List<ContentProviderHolder> providers) {
11160 if (providers == null) {
11164 enforceNotIsolatedCaller("publishContentProviders");
11165 synchronized (this) {
11166 final ProcessRecord r = getRecordForAppLocked(caller);
11167 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11169 throw new SecurityException(
11170 "Unable to find app for caller " + caller
11171 + " (pid=" + Binder.getCallingPid()
11172 + ") when publishing content providers");
11175 final long origId = Binder.clearCallingIdentity();
11177 final int N = providers.size();
11178 for (int i = 0; i < N; i++) {
11179 ContentProviderHolder src = providers.get(i);
11180 if (src == null || src.info == null || src.provider == null) {
11183 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11184 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11186 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11187 mProviderMap.putProviderByClass(comp, dst);
11188 String names[] = dst.info.authority.split(";");
11189 for (int j = 0; j < names.length; j++) {
11190 mProviderMap.putProviderByName(names[j], dst);
11193 int launchingCount = mLaunchingProviders.size();
11195 boolean wasInLaunchingProviders = false;
11196 for (j = 0; j < launchingCount; j++) {
11197 if (mLaunchingProviders.get(j) == dst) {
11198 mLaunchingProviders.remove(j);
11199 wasInLaunchingProviders = true;
11204 if (wasInLaunchingProviders) {
11205 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11207 synchronized (dst) {
11208 dst.provider = src.provider;
11212 updateOomAdjLocked(r);
11213 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11214 src.info.authority);
11218 Binder.restoreCallingIdentity(origId);
11222 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11223 ContentProviderConnection conn;
11225 conn = (ContentProviderConnection)connection;
11226 } catch (ClassCastException e) {
11227 String msg ="refContentProvider: " + connection
11228 + " not a ContentProviderConnection";
11230 throw new IllegalArgumentException(msg);
11232 if (conn == null) {
11233 throw new NullPointerException("connection is null");
11236 synchronized (this) {
11238 conn.numStableIncs += stable;
11240 stable = conn.stableCount + stable;
11242 throw new IllegalStateException("stableCount < 0: " + stable);
11245 if (unstable > 0) {
11246 conn.numUnstableIncs += unstable;
11248 unstable = conn.unstableCount + unstable;
11249 if (unstable < 0) {
11250 throw new IllegalStateException("unstableCount < 0: " + unstable);
11253 if ((stable+unstable) <= 0) {
11254 throw new IllegalStateException("ref counts can't go to zero here: stable="
11255 + stable + " unstable=" + unstable);
11257 conn.stableCount = stable;
11258 conn.unstableCount = unstable;
11263 public void unstableProviderDied(IBinder connection) {
11264 ContentProviderConnection conn;
11266 conn = (ContentProviderConnection)connection;
11267 } catch (ClassCastException e) {
11268 String msg ="refContentProvider: " + connection
11269 + " not a ContentProviderConnection";
11271 throw new IllegalArgumentException(msg);
11273 if (conn == null) {
11274 throw new NullPointerException("connection is null");
11277 // Safely retrieve the content provider associated with the connection.
11278 IContentProvider provider;
11279 synchronized (this) {
11280 provider = conn.provider.provider;
11283 if (provider == null) {
11284 // Um, yeah, we're way ahead of you.
11288 // Make sure the caller is being honest with us.
11289 if (provider.asBinder().pingBinder()) {
11290 // Er, no, still looks good to us.
11291 synchronized (this) {
11292 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11293 + " says " + conn + " died, but we don't agree");
11298 // Well look at that! It's dead!
11299 synchronized (this) {
11300 if (conn.provider.provider != provider) {
11301 // But something changed... good enough.
11305 ProcessRecord proc = conn.provider.proc;
11306 if (proc == null || proc.thread == null) {
11307 // Seems like the process is already cleaned up.
11311 // As far as we're concerned, this is just like receiving a
11312 // death notification... just a bit prematurely.
11313 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11314 + ") early provider death");
11315 final long ident = Binder.clearCallingIdentity();
11317 appDiedLocked(proc);
11319 Binder.restoreCallingIdentity(ident);
11325 public void appNotRespondingViaProvider(IBinder connection) {
11326 enforceCallingPermission(
11327 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11329 final ContentProviderConnection conn = (ContentProviderConnection) connection;
11330 if (conn == null) {
11331 Slog.w(TAG, "ContentProviderConnection is null");
11335 final ProcessRecord host = conn.provider.proc;
11336 if (host == null) {
11337 Slog.w(TAG, "Failed to find hosting ProcessRecord");
11341 mHandler.post(new Runnable() {
11343 public void run() {
11344 mAppErrors.appNotResponding(host, null, null, false,
11345 "ContentProvider not responding");
11350 public final void installSystemProviders() {
11351 List<ProviderInfo> providers;
11352 synchronized (this) {
11353 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11354 providers = generateApplicationProvidersLocked(app);
11355 if (providers != null) {
11356 for (int i=providers.size()-1; i>=0; i--) {
11357 ProviderInfo pi = (ProviderInfo)providers.get(i);
11358 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11359 Slog.w(TAG, "Not installing system proc provider " + pi.name
11360 + ": not system .apk");
11361 providers.remove(i);
11366 if (providers != null) {
11367 mSystemThread.installSystemProviders(providers);
11370 mCoreSettingsObserver = new CoreSettingsObserver(this);
11371 mFontScaleSettingObserver = new FontScaleSettingObserver();
11373 //mUsageStatsService.monitorPackages();
11376 private void startPersistentApps(int matchFlags) {
11377 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11379 synchronized (this) {
11381 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11382 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11383 for (ApplicationInfo app : apps) {
11384 if (!"android".equals(app.packageName)) {
11385 addAppLocked(app, false, null /* ABI override */);
11388 } catch (RemoteException ex) {
11394 * When a user is unlocked, we need to install encryption-unaware providers
11395 * belonging to any running apps.
11397 private void installEncryptionUnawareProviders(int userId) {
11398 // We're only interested in providers that are encryption unaware, and
11399 // we don't care about uninstalled apps, since there's no way they're
11400 // running at this point.
11401 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11403 synchronized (this) {
11404 final int NP = mProcessNames.getMap().size();
11405 for (int ip = 0; ip < NP; ip++) {
11406 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11407 final int NA = apps.size();
11408 for (int ia = 0; ia < NA; ia++) {
11409 final ProcessRecord app = apps.valueAt(ia);
11410 if (app.userId != userId || app.thread == null || app.unlocked) continue;
11412 final int NG = app.pkgList.size();
11413 for (int ig = 0; ig < NG; ig++) {
11415 final String pkgName = app.pkgList.keyAt(ig);
11416 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11417 .getPackageInfo(pkgName, matchFlags, userId);
11418 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11419 for (ProviderInfo pi : pkgInfo.providers) {
11420 // TODO: keep in sync with generateApplicationProvidersLocked
11421 final boolean processMatch = Objects.equals(pi.processName,
11422 app.processName) || pi.multiprocess;
11423 final boolean userMatch = isSingleton(pi.processName,
11424 pi.applicationInfo, pi.name, pi.flags)
11425 ? (app.userId == UserHandle.USER_SYSTEM) : true;
11426 if (processMatch && userMatch) {
11427 Log.v(TAG, "Installing " + pi);
11428 app.thread.scheduleInstallProvider(pi);
11430 Log.v(TAG, "Skipping " + pi);
11434 } catch (RemoteException ignored) {
11443 * Allows apps to retrieve the MIME type of a URI.
11444 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11445 * users, then it does not need permission to access the ContentProvider.
11446 * Either, it needs cross-user uri grants.
11448 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11450 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11451 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11453 public String getProviderMimeType(Uri uri, int userId) {
11454 enforceNotIsolatedCaller("getProviderMimeType");
11455 final String name = uri.getAuthority();
11456 int callingUid = Binder.getCallingUid();
11457 int callingPid = Binder.getCallingPid();
11459 boolean clearedIdentity = false;
11460 synchronized (this) {
11461 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11463 if (canClearIdentity(callingPid, callingUid, userId)) {
11464 clearedIdentity = true;
11465 ident = Binder.clearCallingIdentity();
11467 ContentProviderHolder holder = null;
11469 holder = getContentProviderExternalUnchecked(name, null, userId);
11470 if (holder != null) {
11471 return holder.provider.getType(uri);
11473 } catch (RemoteException e) {
11474 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11476 } catch (Exception e) {
11477 Log.w(TAG, "Exception while determining type of " + uri, e);
11480 // We need to clear the identity to call removeContentProviderExternalUnchecked
11481 if (!clearedIdentity) {
11482 ident = Binder.clearCallingIdentity();
11485 if (holder != null) {
11486 removeContentProviderExternalUnchecked(name, null, userId);
11489 Binder.restoreCallingIdentity(ident);
11496 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11497 if (UserHandle.getUserId(callingUid) == userId) {
11500 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11501 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11502 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11503 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11509 // =========================================================
11510 // GLOBAL MANAGEMENT
11511 // =========================================================
11513 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11514 boolean isolated, int isolatedUid) {
11515 String proc = customProcess != null ? customProcess : info.processName;
11516 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11517 final int userId = UserHandle.getUserId(info.uid);
11518 int uid = info.uid;
11520 if (isolatedUid == 0) {
11521 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11523 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11524 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11525 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11527 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11528 mNextIsolatedProcessUid++;
11529 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11530 // No process for this uid, use it.
11534 if (stepsLeft <= 0) {
11539 // Special case for startIsolatedProcess (internal only), where
11540 // the uid of the isolated process is specified by the caller.
11544 // Register the isolated UID with this application so BatteryStats knows to
11545 // attribute resource usage to the application.
11547 // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11548 // about the process state of the isolated UID *before* it is registered with the
11549 // owning application.
11550 mBatteryStatsService.addIsolatedUid(uid, info.uid);
11552 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11553 if (!mBooted && !mBooting
11554 && userId == UserHandle.USER_SYSTEM
11555 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11556 r.persistent = true;
11558 addProcessNameLocked(r);
11562 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11563 String abiOverride) {
11566 app = getProcessRecordLocked(info.processName, info.uid, true);
11572 app = newProcessRecordLocked(info, null, isolated, 0);
11573 updateLruProcessLocked(app, false, null);
11574 updateOomAdjLocked();
11577 // This package really, really can not be stopped.
11579 AppGlobals.getPackageManager().setPackageStoppedState(
11580 info.packageName, false, UserHandle.getUserId(app.uid));
11581 } catch (RemoteException e) {
11582 } catch (IllegalArgumentException e) {
11583 Slog.w(TAG, "Failed trying to unstop package "
11584 + info.packageName + ": " + e);
11587 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11588 app.persistent = true;
11589 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11591 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11592 mPersistentStartingProcesses.add(app);
11593 startProcessLocked(app, "added application", app.processName, abiOverride,
11594 null /* entryPoint */, null /* entryPointArgs */);
11600 public void unhandledBack() {
11601 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11602 "unhandledBack()");
11604 synchronized(this) {
11605 final long origId = Binder.clearCallingIdentity();
11607 getFocusedStack().unhandledBackLocked();
11609 Binder.restoreCallingIdentity(origId);
11614 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11615 enforceNotIsolatedCaller("openContentUri");
11616 final int userId = UserHandle.getCallingUserId();
11617 String name = uri.getAuthority();
11618 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11619 ParcelFileDescriptor pfd = null;
11621 // We record the binder invoker's uid in thread-local storage before
11622 // going to the content provider to open the file. Later, in the code
11623 // that handles all permissions checks, we look for this uid and use
11624 // that rather than the Activity Manager's own uid. The effect is that
11625 // we do the check against the caller's permissions even though it looks
11626 // to the content provider like the Activity Manager itself is making
11628 Binder token = new Binder();
11629 sCallerIdentity.set(new Identity(
11630 token, Binder.getCallingPid(), Binder.getCallingUid()));
11632 pfd = cph.provider.openFile(null, uri, "r", null, token);
11633 } catch (FileNotFoundException e) {
11634 // do nothing; pfd will be returned null
11636 // Ensure that whatever happens, we clean up the identity state
11637 sCallerIdentity.remove();
11638 // Ensure we're done with the provider.
11639 removeContentProviderExternalUnchecked(name, null, userId);
11642 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11647 // Actually is sleeping or shutting down or whatever else in the future
11648 // is an inactive state.
11649 boolean isSleepingOrShuttingDownLocked() {
11650 return isSleepingLocked() || mShuttingDown;
11653 boolean isShuttingDownLocked() {
11654 return mShuttingDown;
11657 boolean isSleepingLocked() {
11661 void onWakefulnessChanged(int wakefulness) {
11662 synchronized(this) {
11663 mWakefulness = wakefulness;
11664 updateSleepIfNeededLocked();
11668 void finishRunningVoiceLocked() {
11669 if (mRunningVoice != null) {
11670 mRunningVoice = null;
11671 mVoiceWakeLock.release();
11672 updateSleepIfNeededLocked();
11676 void startTimeTrackingFocusedActivityLocked() {
11677 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11678 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11682 void updateSleepIfNeededLocked() {
11683 if (mSleeping && !shouldSleepLocked()) {
11685 startTimeTrackingFocusedActivityLocked();
11686 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11687 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11688 updateOomAdjLocked();
11689 } else if (!mSleeping && shouldSleepLocked()) {
11691 if (mCurAppTimeTracker != null) {
11692 mCurAppTimeTracker.stop();
11694 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11695 mStackSupervisor.goingToSleepLocked();
11696 updateOomAdjLocked();
11698 // Initialize the wake times of all processes.
11699 checkExcessivePowerUsageLocked(false);
11700 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11701 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11702 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11706 private boolean shouldSleepLocked() {
11707 // Resume applications while running a voice interactor.
11708 if (mRunningVoice != null) {
11712 // TODO: Transform the lock screen state into a sleep token instead.
11713 switch (mWakefulness) {
11714 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11715 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11716 case PowerManagerInternal.WAKEFULNESS_DOZING:
11717 // Pause applications whenever the lock screen is shown or any sleep
11718 // tokens have been acquired.
11719 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11720 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11722 // If we're asleep then pause applications unconditionally.
11727 /** Pokes the task persister. */
11728 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11729 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11732 /** Notifies all listeners when the task stack has changed. */
11733 void notifyTaskStackChangedLocked() {
11734 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11735 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11736 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11737 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11740 /** Notifies all listeners when an Activity is pinned. */
11741 void notifyActivityPinnedLocked() {
11742 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11743 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11747 * Notifies all listeners when an attempt was made to start an an activity that is already
11748 * running in the pinned stack and the activity was not actually started, but the task is
11749 * either brought to the front or a new Intent is delivered to it.
11751 void notifyPinnedActivityRestartAttemptLocked() {
11752 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11753 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11756 /** Notifies all listeners when the pinned stack animation ends. */
11758 public void notifyPinnedStackAnimationEnded() {
11759 synchronized (this) {
11760 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11761 mHandler.obtainMessage(
11762 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11767 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11768 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11772 public boolean shutdown(int timeout) {
11773 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11774 != PackageManager.PERMISSION_GRANTED) {
11775 throw new SecurityException("Requires permission "
11776 + android.Manifest.permission.SHUTDOWN);
11779 boolean timedout = false;
11781 synchronized(this) {
11782 mShuttingDown = true;
11783 updateEventDispatchingLocked();
11784 timedout = mStackSupervisor.shutdownLocked(timeout);
11787 mAppOpsService.shutdown();
11788 if (mUsageStatsService != null) {
11789 mUsageStatsService.prepareShutdown();
11791 mBatteryStatsService.shutdown();
11792 synchronized (this) {
11793 mProcessStats.shutdownLocked();
11794 notifyTaskPersisterLocked(null, true);
11800 public final void activitySlept(IBinder token) {
11801 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11803 final long origId = Binder.clearCallingIdentity();
11805 synchronized (this) {
11806 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11808 mStackSupervisor.activitySleptLocked(r);
11812 Binder.restoreCallingIdentity(origId);
11815 private String lockScreenShownToString() {
11816 switch (mLockScreenShown) {
11817 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11818 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11819 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11820 default: return "Unknown=" + mLockScreenShown;
11824 void logLockScreen(String msg) {
11825 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11826 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11827 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11828 + " mSleeping=" + mSleeping);
11831 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11832 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11833 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11834 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11835 boolean wasRunningVoice = mRunningVoice != null;
11836 mRunningVoice = session;
11837 if (!wasRunningVoice) {
11838 mVoiceWakeLock.acquire();
11839 updateSleepIfNeededLocked();
11844 private void updateEventDispatchingLocked() {
11845 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11848 public void setLockScreenShown(boolean showing, boolean occluded) {
11849 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11850 != PackageManager.PERMISSION_GRANTED) {
11851 throw new SecurityException("Requires permission "
11852 + android.Manifest.permission.DEVICE_POWER);
11855 synchronized(this) {
11856 long ident = Binder.clearCallingIdentity();
11858 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11859 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11860 if (showing && occluded) {
11861 // The lock screen is currently showing, but is occluded by a window that can
11862 // show on top of the lock screen. In this can we want to dismiss the docked
11863 // stack since it will be complicated/risky to try to put the activity on top
11864 // of the lock screen in the right fullscreen configuration.
11865 mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11866 mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11869 updateSleepIfNeededLocked();
11871 Binder.restoreCallingIdentity(ident);
11877 public void notifyLockedProfile(@UserIdInt int userId) {
11879 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11880 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11882 } catch (RemoteException ex) {
11883 throw new SecurityException("Fail to check is caller a privileged app", ex);
11886 synchronized (this) {
11887 if (mStackSupervisor.isUserLockedProfile(userId)) {
11888 final long ident = Binder.clearCallingIdentity();
11890 final int currentUserId = mUserController.getCurrentUserIdLocked();
11892 // Drop locked freeform tasks out into the fullscreen stack.
11893 // TODO: Redact the tasks in place. It's much better to keep them on the screen
11894 // where they were before, but in an obscured state.
11895 mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11897 if (mUserController.isLockScreenDisabled(currentUserId)) {
11898 // If there is no device lock, we will show the profile's credential page.
11899 mActivityStarter.showConfirmDeviceCredential(userId);
11901 // Showing launcher to avoid user entering credential twice.
11902 startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11905 Binder.restoreCallingIdentity(ident);
11912 public void startConfirmDeviceCredentialIntent(Intent intent) {
11913 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11914 synchronized (this) {
11915 final long ident = Binder.clearCallingIdentity();
11917 mActivityStarter.startConfirmCredentialIntent(intent);
11919 Binder.restoreCallingIdentity(ident);
11925 public void stopAppSwitches() {
11926 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11927 != PackageManager.PERMISSION_GRANTED) {
11928 throw new SecurityException("viewquires permission "
11929 + android.Manifest.permission.STOP_APP_SWITCHES);
11932 synchronized(this) {
11933 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11934 + APP_SWITCH_DELAY_TIME;
11935 mDidAppSwitch = false;
11936 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11937 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11938 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11942 public void resumeAppSwitches() {
11943 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11944 != PackageManager.PERMISSION_GRANTED) {
11945 throw new SecurityException("Requires permission "
11946 + android.Manifest.permission.STOP_APP_SWITCHES);
11949 synchronized(this) {
11950 // Note that we don't execute any pending app switches... we will
11951 // let those wait until either the timeout, or the next start
11952 // activity request.
11953 mAppSwitchesAllowedTime = 0;
11957 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11958 int callingPid, int callingUid, String name) {
11959 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11963 int perm = checkComponentPermission(
11964 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11965 sourceUid, -1, true);
11966 if (perm == PackageManager.PERMISSION_GRANTED) {
11970 // If the actual IPC caller is different from the logical source, then
11971 // also see if they are allowed to control app switches.
11972 if (callingUid != -1 && callingUid != sourceUid) {
11973 perm = checkComponentPermission(
11974 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11975 callingUid, -1, true);
11976 if (perm == PackageManager.PERMISSION_GRANTED) {
11981 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11985 public void setDebugApp(String packageName, boolean waitForDebugger,
11986 boolean persistent) {
11987 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11990 long ident = Binder.clearCallingIdentity();
11992 // Note that this is not really thread safe if there are multiple
11993 // callers into it at the same time, but that's not a situation we
11996 final ContentResolver resolver = mContext.getContentResolver();
11997 Settings.Global.putString(
11998 resolver, Settings.Global.DEBUG_APP,
12000 Settings.Global.putInt(
12001 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12002 waitForDebugger ? 1 : 0);
12005 synchronized (this) {
12007 mOrigDebugApp = mDebugApp;
12008 mOrigWaitForDebugger = mWaitForDebugger;
12010 mDebugApp = packageName;
12011 mWaitForDebugger = waitForDebugger;
12012 mDebugTransient = !persistent;
12013 if (packageName != null) {
12014 forceStopPackageLocked(packageName, -1, false, false, true, true,
12015 false, UserHandle.USER_ALL, "set debug app");
12019 Binder.restoreCallingIdentity(ident);
12023 void setTrackAllocationApp(ApplicationInfo app, String processName) {
12024 synchronized (this) {
12025 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12026 if (!isDebuggable) {
12027 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12028 throw new SecurityException("Process not debuggable: " + app.packageName);
12032 mTrackAllocationApp = processName;
12036 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12037 synchronized (this) {
12038 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12039 if (!isDebuggable) {
12040 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12041 throw new SecurityException("Process not debuggable: " + app.packageName);
12044 mProfileApp = processName;
12045 mProfileFile = profilerInfo.profileFile;
12046 if (mProfileFd != null) {
12048 mProfileFd.close();
12049 } catch (IOException e) {
12053 mProfileFd = profilerInfo.profileFd;
12054 mSamplingInterval = profilerInfo.samplingInterval;
12055 mAutoStopProfiler = profilerInfo.autoStopProfiler;
12060 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12061 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12062 if (!isDebuggable) {
12063 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12064 throw new SecurityException("Process not debuggable: " + app.packageName);
12067 mNativeDebuggingApp = processName;
12071 public void setAlwaysFinish(boolean enabled) {
12072 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12073 "setAlwaysFinish()");
12075 long ident = Binder.clearCallingIdentity();
12077 Settings.Global.putInt(
12078 mContext.getContentResolver(),
12079 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12081 synchronized (this) {
12082 mAlwaysFinishActivities = enabled;
12085 Binder.restoreCallingIdentity(ident);
12090 public void setLenientBackgroundCheck(boolean enabled) {
12091 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12092 "setLenientBackgroundCheck()");
12094 long ident = Binder.clearCallingIdentity();
12096 Settings.Global.putInt(
12097 mContext.getContentResolver(),
12098 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12100 synchronized (this) {
12101 mLenientBackgroundCheck = enabled;
12104 Binder.restoreCallingIdentity(ident);
12109 public void setActivityController(IActivityController controller, boolean imAMonkey) {
12110 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12111 "setActivityController()");
12112 synchronized (this) {
12113 mController = controller;
12114 mControllerIsAMonkey = imAMonkey;
12115 Watchdog.getInstance().setActivityController(controller);
12120 public void setUserIsMonkey(boolean userIsMonkey) {
12121 synchronized (this) {
12122 synchronized (mPidsSelfLocked) {
12123 final int callingPid = Binder.getCallingPid();
12124 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12125 if (precessRecord == null) {
12126 throw new SecurityException("Unknown process: " + callingPid);
12128 if (precessRecord.instrumentationUiAutomationConnection == null) {
12129 throw new SecurityException("Only an instrumentation process "
12130 + "with a UiAutomation can call setUserIsMonkey");
12133 mUserIsMonkey = userIsMonkey;
12138 public boolean isUserAMonkey() {
12139 synchronized (this) {
12140 // If there is a controller also implies the user is a monkey.
12141 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12145 public void requestBugReport(int bugreportType) {
12146 String service = null;
12147 switch (bugreportType) {
12148 case ActivityManager.BUGREPORT_OPTION_FULL:
12149 service = "bugreport";
12151 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12152 service = "bugreportplus";
12154 case ActivityManager.BUGREPORT_OPTION_REMOTE:
12155 service = "bugreportremote";
12157 case ActivityManager.BUGREPORT_OPTION_WEAR:
12158 service = "bugreportwear";
12161 if (service == null) {
12162 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12165 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12166 SystemProperties.set("ctl.start", service);
12169 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12170 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12173 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12174 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12175 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12177 return KEY_DISPATCHING_TIMEOUT;
12181 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12182 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12183 != PackageManager.PERMISSION_GRANTED) {
12184 throw new SecurityException("Requires permission "
12185 + android.Manifest.permission.FILTER_EVENTS);
12187 ProcessRecord proc;
12189 synchronized (this) {
12190 synchronized (mPidsSelfLocked) {
12191 proc = mPidsSelfLocked.get(pid);
12193 timeout = getInputDispatchingTimeoutLocked(proc);
12196 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12204 * Handle input dispatching timeouts.
12205 * Returns whether input dispatching should be aborted or not.
12207 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12208 final ActivityRecord activity, final ActivityRecord parent,
12209 final boolean aboveSystem, String reason) {
12210 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12211 != PackageManager.PERMISSION_GRANTED) {
12212 throw new SecurityException("Requires permission "
12213 + android.Manifest.permission.FILTER_EVENTS);
12216 final String annotation;
12217 if (reason == null) {
12218 annotation = "Input dispatching timed out";
12220 annotation = "Input dispatching timed out (" + reason + ")";
12223 if (proc != null) {
12224 synchronized (this) {
12225 if (proc.debugging) {
12230 // Give more time since we were dexopting.
12231 mDidDexOpt = false;
12235 if (proc.instrumentationClass != null) {
12236 Bundle info = new Bundle();
12237 info.putString("shortMsg", "keyDispatchingTimedOut");
12238 info.putString("longMsg", annotation);
12239 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12243 mHandler.post(new Runnable() {
12245 public void run() {
12246 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12255 public Bundle getAssistContextExtras(int requestType) {
12256 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12257 null, null, true /* focused */, true /* newSessionId */,
12258 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12262 synchronized (pae) {
12263 while (!pae.haveResult) {
12266 } catch (InterruptedException e) {
12270 synchronized (this) {
12271 buildAssistBundleLocked(pae, pae.result);
12272 mPendingAssistExtras.remove(pae);
12273 mUiHandler.removeCallbacks(pae);
12279 public boolean isAssistDataAllowedOnCurrentActivity() {
12281 synchronized (this) {
12282 userId = mUserController.getCurrentUserIdLocked();
12283 ActivityRecord activity = getFocusedStack().topActivity();
12284 if (activity == null) {
12287 userId = activity.userId;
12289 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12290 Context.DEVICE_POLICY_SERVICE);
12291 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12295 public boolean showAssistFromActivity(IBinder token, Bundle args) {
12296 long ident = Binder.clearCallingIdentity();
12298 synchronized (this) {
12299 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12300 ActivityRecord top = getFocusedStack().topActivity();
12301 if (top != caller) {
12302 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12303 + " is not current top " + top);
12306 if (!top.nowVisible) {
12307 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12308 + " is not visible");
12312 AssistUtils utils = new AssistUtils(mContext);
12313 return utils.showSessionForActiveService(args,
12314 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12316 Binder.restoreCallingIdentity(ident);
12321 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12322 Bundle receiverExtras,
12323 IBinder activityToken, boolean focused, boolean newSessionId) {
12324 return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12325 activityToken, focused, newSessionId,
12326 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12330 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12331 IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12332 boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12333 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12334 "enqueueAssistContext()");
12335 synchronized (this) {
12336 ActivityRecord activity = getFocusedStack().topActivity();
12337 if (activity == null) {
12338 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12341 if (activity.app == null || activity.app.thread == null) {
12342 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12346 if (activityToken != null) {
12347 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12348 if (activity != caller) {
12349 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12350 + " is not current top " + activity);
12355 activity = ActivityRecord.forTokenLocked(activityToken);
12356 if (activity == null) {
12357 Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12358 + " couldn't be found");
12363 PendingAssistExtras pae;
12364 Bundle extras = new Bundle();
12365 if (args != null) {
12366 extras.putAll(args);
12368 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12369 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12370 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12372 // Increment the sessionId if necessary
12373 if (newSessionId) {
12377 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12378 requestType, mViSessionId);
12379 mPendingAssistExtras.add(pae);
12380 mUiHandler.postDelayed(pae, timeout);
12381 } catch (RemoteException e) {
12382 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12389 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12390 IResultReceiver receiver;
12391 synchronized (this) {
12392 mPendingAssistExtras.remove(pae);
12393 receiver = pae.receiver;
12395 if (receiver != null) {
12396 // Caller wants result sent back to them.
12397 Bundle sendBundle = new Bundle();
12398 // At least return the receiver extras
12399 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12400 pae.receiverExtras);
12402 pae.receiver.send(0, sendBundle);
12403 } catch (RemoteException e) {
12408 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12409 if (result != null) {
12410 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12412 if (pae.hint != null) {
12413 pae.extras.putBoolean(pae.hint, true);
12417 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12418 AssistContent content, Uri referrer) {
12419 PendingAssistExtras pae = (PendingAssistExtras)token;
12420 synchronized (pae) {
12421 pae.result = extras;
12422 pae.structure = structure;
12423 pae.content = content;
12424 if (referrer != null) {
12425 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12427 pae.haveResult = true;
12429 if (pae.intent == null && pae.receiver == null) {
12430 // Caller is just waiting for the result.
12435 // We are now ready to launch the assist activity.
12436 IResultReceiver sendReceiver = null;
12437 Bundle sendBundle = null;
12438 synchronized (this) {
12439 buildAssistBundleLocked(pae, extras);
12440 boolean exists = mPendingAssistExtras.remove(pae);
12441 mUiHandler.removeCallbacks(pae);
12446 if ((sendReceiver=pae.receiver) != null) {
12447 // Caller wants result sent back to them.
12448 sendBundle = new Bundle();
12449 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12450 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12451 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12452 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12453 pae.receiverExtras);
12456 if (sendReceiver != null) {
12458 sendReceiver.send(0, sendBundle);
12459 } catch (RemoteException e) {
12464 long ident = Binder.clearCallingIdentity();
12466 pae.intent.replaceExtras(pae.extras);
12467 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12468 | Intent.FLAG_ACTIVITY_SINGLE_TOP
12469 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12470 closeSystemDialogs("assist");
12472 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12473 } catch (ActivityNotFoundException e) {
12474 Slog.w(TAG, "No activity to handle assist action.", e);
12477 Binder.restoreCallingIdentity(ident);
12481 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12483 return enqueueAssistContext(requestType, intent, hint, null, null, null,
12484 true /* focused */, true /* newSessionId */,
12485 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12488 public void registerProcessObserver(IProcessObserver observer) {
12489 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12490 "registerProcessObserver()");
12491 synchronized (this) {
12492 mProcessObservers.register(observer);
12497 public void unregisterProcessObserver(IProcessObserver observer) {
12498 synchronized (this) {
12499 mProcessObservers.unregister(observer);
12504 public void registerUidObserver(IUidObserver observer, int which) {
12505 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12506 "registerUidObserver()");
12507 synchronized (this) {
12508 mUidObservers.register(observer, which);
12513 public void unregisterUidObserver(IUidObserver observer) {
12514 synchronized (this) {
12515 mUidObservers.unregister(observer);
12520 public boolean convertFromTranslucent(IBinder token) {
12521 final long origId = Binder.clearCallingIdentity();
12523 synchronized (this) {
12524 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12528 final boolean translucentChanged = r.changeWindowTranslucency(true);
12529 if (translucentChanged) {
12530 r.task.stack.releaseBackgroundResources(r);
12531 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12533 mWindowManager.setAppFullscreen(token, true);
12534 return translucentChanged;
12537 Binder.restoreCallingIdentity(origId);
12542 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12543 final long origId = Binder.clearCallingIdentity();
12545 synchronized (this) {
12546 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12550 int index = r.task.mActivities.lastIndexOf(r);
12552 ActivityRecord under = r.task.mActivities.get(index - 1);
12553 under.returningOptions = options;
12555 final boolean translucentChanged = r.changeWindowTranslucency(false);
12556 if (translucentChanged) {
12557 r.task.stack.convertActivityToTranslucent(r);
12559 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12560 mWindowManager.setAppFullscreen(token, false);
12561 return translucentChanged;
12564 Binder.restoreCallingIdentity(origId);
12569 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12570 final long origId = Binder.clearCallingIdentity();
12572 synchronized (this) {
12573 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12575 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12580 Binder.restoreCallingIdentity(origId);
12585 public boolean isBackgroundVisibleBehind(IBinder token) {
12586 final long origId = Binder.clearCallingIdentity();
12588 synchronized (this) {
12589 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12590 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12591 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12592 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12596 Binder.restoreCallingIdentity(origId);
12601 public ActivityOptions getActivityOptions(IBinder token) {
12602 final long origId = Binder.clearCallingIdentity();
12604 synchronized (this) {
12605 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12607 final ActivityOptions activityOptions = r.pendingOptions;
12608 r.pendingOptions = null;
12609 return activityOptions;
12614 Binder.restoreCallingIdentity(origId);
12619 public void setImmersive(IBinder token, boolean immersive) {
12620 synchronized(this) {
12621 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12623 throw new IllegalArgumentException();
12625 r.immersive = immersive;
12627 // update associated state if we're frontmost
12628 if (r == mFocusedActivity) {
12629 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12630 applyUpdateLockStateLocked(r);
12636 public boolean isImmersive(IBinder token) {
12637 synchronized (this) {
12638 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12640 throw new IllegalArgumentException();
12642 return r.immersive;
12646 public void setVrThread(int tid) {
12647 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12648 throw new UnsupportedOperationException("VR mode not supported on this device!");
12651 synchronized (this) {
12652 ProcessRecord proc;
12653 synchronized (mPidsSelfLocked) {
12654 final int pid = Binder.getCallingPid();
12655 proc = mPidsSelfLocked.get(pid);
12657 if (proc != null && mInVrMode && tid >= 0) {
12658 // ensure the tid belongs to the process
12659 if (!Process.isThreadInProcess(pid, tid)) {
12660 throw new IllegalArgumentException("VR thread does not belong to process");
12663 // reset existing VR thread to CFS if this thread still exists and belongs to
12664 // the calling process
12665 if (proc.vrThreadTid != 0
12666 && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12668 Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12669 } catch (IllegalArgumentException e) {
12670 // Ignore this. Only occurs in race condition where previous VR thread
12671 // was destroyed during this method call.
12675 proc.vrThreadTid = tid;
12677 // promote to FIFO now if the tid is non-zero
12679 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12680 proc.vrThreadTid > 0) {
12681 Process.setThreadScheduler(proc.vrThreadTid,
12682 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12684 } catch (IllegalArgumentException e) {
12685 Slog.e(TAG, "Failed to set scheduling policy, thread does"
12686 + " not exist:\n" + e);
12694 public void setRenderThread(int tid) {
12695 synchronized (this) {
12696 ProcessRecord proc;
12697 synchronized (mPidsSelfLocked) {
12698 int pid = Binder.getCallingPid();
12699 proc = mPidsSelfLocked.get(pid);
12700 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12701 // ensure the tid belongs to the process
12702 if (!Process.isThreadInProcess(pid, tid)) {
12703 throw new IllegalArgumentException(
12704 "Render thread does not belong to process");
12706 proc.renderThreadTid = tid;
12707 if (DEBUG_OOM_ADJ) {
12708 Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12710 // promote to FIFO now
12711 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12712 if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12713 if (mUseFifoUiScheduling) {
12714 Process.setThreadScheduler(proc.renderThreadTid,
12715 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12717 Process.setThreadPriority(proc.renderThreadTid, -10);
12721 if (DEBUG_OOM_ADJ) {
12722 Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12723 "PID: " + pid + ", TID: " + tid + " FIFO: " +
12724 mUseFifoUiScheduling);
12732 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12733 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12734 throw new UnsupportedOperationException("VR mode not supported on this device!");
12737 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12740 synchronized (this) {
12741 r = ActivityRecord.isInStackLocked(token);
12745 throw new IllegalArgumentException();
12749 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12750 VrManagerInternal.NO_ERROR) {
12754 synchronized(this) {
12755 r.requestedVrComponent = (enabled) ? packageName : null;
12757 // Update associated state if this activity is currently focused
12758 if (r == mFocusedActivity) {
12759 applyUpdateVrModeLocked(r);
12766 public boolean isVrModePackageEnabled(ComponentName packageName) {
12767 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12768 throw new UnsupportedOperationException("VR mode not supported on this device!");
12771 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12773 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12774 VrManagerInternal.NO_ERROR;
12777 public boolean isTopActivityImmersive() {
12778 enforceNotIsolatedCaller("startActivity");
12779 synchronized (this) {
12780 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12781 return (r != null) ? r.immersive : false;
12786 public boolean isTopOfTask(IBinder token) {
12787 synchronized (this) {
12788 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12790 throw new IllegalArgumentException();
12792 return r.task.getTopActivity() == r;
12797 public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12798 if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12799 String msg = "Permission Denial: setHasTopUi() from pid="
12800 + Binder.getCallingPid()
12801 + ", uid=" + Binder.getCallingUid()
12802 + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12804 throw new SecurityException(msg);
12806 final int pid = Binder.getCallingPid();
12807 final long origId = Binder.clearCallingIdentity();
12809 synchronized (this) {
12810 boolean changed = false;
12812 synchronized (mPidsSelfLocked) {
12813 pr = mPidsSelfLocked.get(pid);
12815 Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12818 if (pr.hasTopUi != hasTopUi) {
12819 Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12820 pr.hasTopUi = hasTopUi;
12825 updateOomAdjLocked(pr);
12829 Binder.restoreCallingIdentity(origId);
12833 public final void enterSafeMode() {
12834 synchronized(this) {
12835 // It only makes sense to do this before the system is ready
12836 // and started launching other packages.
12837 if (!mSystemReady) {
12839 AppGlobals.getPackageManager().enterSafeMode();
12840 } catch (RemoteException e) {
12848 public final void showSafeModeOverlay() {
12849 View v = LayoutInflater.from(mContext).inflate(
12850 com.android.internal.R.layout.safe_mode, null);
12851 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12852 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12853 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12854 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12855 lp.gravity = Gravity.BOTTOM | Gravity.START;
12856 lp.format = v.getBackground().getOpacity();
12857 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12858 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12859 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12860 ((WindowManager)mContext.getSystemService(
12861 Context.WINDOW_SERVICE)).addView(v, lp);
12864 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12865 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12868 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12869 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12870 synchronized (stats) {
12871 if (mBatteryStatsService.isOnBattery()) {
12872 mBatteryStatsService.enforceCallingPermission();
12873 int MY_UID = Binder.getCallingUid();
12875 if (sender == null) {
12878 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12880 BatteryStatsImpl.Uid.Pkg pkg =
12881 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12882 sourcePkg != null ? sourcePkg : rec.key.packageName);
12883 pkg.noteWakeupAlarmLocked(tag);
12888 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12889 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12892 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12893 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12894 synchronized (stats) {
12895 mBatteryStatsService.enforceCallingPermission();
12896 int MY_UID = Binder.getCallingUid();
12898 if (sender == null) {
12901 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12903 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12907 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12908 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12911 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12912 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12913 synchronized (stats) {
12914 mBatteryStatsService.enforceCallingPermission();
12915 int MY_UID = Binder.getCallingUid();
12917 if (sender == null) {
12920 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12922 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12926 public boolean killPids(int[] pids, String pReason, boolean secure) {
12927 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12928 throw new SecurityException("killPids only available to the system");
12930 String reason = (pReason == null) ? "Unknown" : pReason;
12931 // XXX Note: don't acquire main activity lock here, because the window
12932 // manager calls in with its locks held.
12934 boolean killed = false;
12935 synchronized (mPidsSelfLocked) {
12937 for (int i=0; i<pids.length; i++) {
12938 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12939 if (proc != null) {
12940 int type = proc.setAdj;
12941 if (type > worstType) {
12947 // If the worst oom_adj is somewhere in the cached proc LRU range,
12948 // then constrain it so we will kill all cached procs.
12949 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12950 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12951 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12954 // If this is not a secure call, don't let it kill processes that
12956 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12957 worstType = ProcessList.SERVICE_ADJ;
12960 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12961 for (int i=0; i<pids.length; i++) {
12962 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12963 if (proc == null) {
12966 int adj = proc.setAdj;
12967 if (adj >= worstType && !proc.killedByAm) {
12968 proc.kill(reason, true);
12977 public void killUid(int appId, int userId, String reason) {
12978 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12979 synchronized (this) {
12980 final long identity = Binder.clearCallingIdentity();
12982 killPackageProcessesLocked(null, appId, userId,
12983 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12984 reason != null ? reason : "kill uid");
12986 Binder.restoreCallingIdentity(identity);
12992 public boolean killProcessesBelowForeground(String reason) {
12993 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12994 throw new SecurityException("killProcessesBelowForeground() only available to system");
12997 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13000 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13001 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13002 throw new SecurityException("killProcessesBelowAdj() only available to system");
13005 boolean killed = false;
13006 synchronized (mPidsSelfLocked) {
13007 final int size = mPidsSelfLocked.size();
13008 for (int i = 0; i < size; i++) {
13009 final int pid = mPidsSelfLocked.keyAt(i);
13010 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13011 if (proc == null) continue;
13013 final int adj = proc.setAdj;
13014 if (adj > belowAdj && !proc.killedByAm) {
13015 proc.kill(reason, true);
13024 public void hang(final IBinder who, boolean allowRestart) {
13025 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13026 != PackageManager.PERMISSION_GRANTED) {
13027 throw new SecurityException("Requires permission "
13028 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13031 final IBinder.DeathRecipient death = new DeathRecipient() {
13033 public void binderDied() {
13034 synchronized (this) {
13041 who.linkToDeath(death, 0);
13042 } catch (RemoteException e) {
13043 Slog.w(TAG, "hang: given caller IBinder is already dead.");
13047 synchronized (this) {
13048 Watchdog.getInstance().setAllowRestart(allowRestart);
13049 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13050 synchronized (death) {
13051 while (who.isBinderAlive()) {
13054 } catch (InterruptedException e) {
13058 Watchdog.getInstance().setAllowRestart(true);
13063 public void restart() {
13064 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13065 != PackageManager.PERMISSION_GRANTED) {
13066 throw new SecurityException("Requires permission "
13067 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13070 Log.i(TAG, "Sending shutdown broadcast...");
13072 BroadcastReceiver br = new BroadcastReceiver() {
13073 @Override public void onReceive(Context context, Intent intent) {
13074 // Now the broadcast is done, finish up the low-level shutdown.
13075 Log.i(TAG, "Shutting down activity manager...");
13077 Log.i(TAG, "Shutdown complete, restarting!");
13078 Process.killProcess(Process.myPid());
13083 // First send the high-level shut down broadcast.
13084 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13085 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13086 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13087 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13088 mContext.sendOrderedBroadcastAsUser(intent,
13089 UserHandle.ALL, null, br, mHandler, 0, null, null);
13091 br.onReceive(mContext, intent);
13094 private long getLowRamTimeSinceIdle(long now) {
13095 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13099 public void performIdleMaintenance() {
13100 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13101 != PackageManager.PERMISSION_GRANTED) {
13102 throw new SecurityException("Requires permission "
13103 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13106 synchronized (this) {
13107 final long now = SystemClock.uptimeMillis();
13108 final long timeSinceLastIdle = now - mLastIdleTime;
13109 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13110 mLastIdleTime = now;
13111 mLowRamTimeSinceLastIdle = 0;
13112 if (mLowRamStartTime != 0) {
13113 mLowRamStartTime = now;
13116 StringBuilder sb = new StringBuilder(128);
13117 sb.append("Idle maintenance over ");
13118 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13119 sb.append(" low RAM for ");
13120 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13121 Slog.i(TAG, sb.toString());
13123 // If at least 1/3 of our time since the last idle period has been spent
13124 // with RAM low, then we want to kill processes.
13125 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13127 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13128 ProcessRecord proc = mLruProcesses.get(i);
13129 if (proc.notCachedSinceIdle) {
13130 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13131 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13132 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13133 if (doKilling && proc.initialIdlePss != 0
13134 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13135 sb = new StringBuilder(128);
13137 sb.append(proc.processName);
13138 sb.append(" in idle maint: pss=");
13139 sb.append(proc.lastPss);
13140 sb.append(", swapPss=");
13141 sb.append(proc.lastSwapPss);
13142 sb.append(", initialPss=");
13143 sb.append(proc.initialIdlePss);
13144 sb.append(", period=");
13145 TimeUtils.formatDuration(timeSinceLastIdle, sb);
13146 sb.append(", lowRamPeriod=");
13147 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13148 Slog.wtfQuiet(TAG, sb.toString());
13149 proc.kill("idle maint (pss " + proc.lastPss
13150 + " from " + proc.initialIdlePss + ")", true);
13153 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13154 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13155 proc.notCachedSinceIdle = true;
13156 proc.initialIdlePss = 0;
13157 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13158 mTestPssMode, isSleepingLocked(), now);
13162 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13163 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13168 public void sendIdleJobTrigger() {
13169 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13170 != PackageManager.PERMISSION_GRANTED) {
13171 throw new SecurityException("Requires permission "
13172 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13175 final long ident = Binder.clearCallingIdentity();
13177 Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13178 .setPackage("android")
13179 .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13180 broadcastIntent(null, intent, null, null, 0, null, null, null,
13181 android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13183 Binder.restoreCallingIdentity(ident);
13187 private void retrieveSettings() {
13188 final ContentResolver resolver = mContext.getContentResolver();
13189 final boolean freeformWindowManagement =
13190 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13191 || Settings.Global.getInt(
13192 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13193 final boolean supportsPictureInPicture =
13194 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13196 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13197 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13198 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13199 final boolean alwaysFinishActivities =
13200 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13201 final boolean lenientBackgroundCheck =
13202 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13203 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13204 final boolean forceResizable = Settings.Global.getInt(
13205 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13206 final boolean supportsLeanbackOnly =
13207 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13209 // Transfer any global setting for forcing RTL layout, into a System Property
13210 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13212 final Configuration configuration = new Configuration();
13213 Settings.System.getConfiguration(resolver, configuration);
13215 // This will take care of setting the correct layout direction flags
13216 configuration.setLayoutDirection(configuration.locale);
13219 synchronized (this) {
13220 mDebugApp = mOrigDebugApp = debugApp;
13221 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13222 mAlwaysFinishActivities = alwaysFinishActivities;
13223 mLenientBackgroundCheck = lenientBackgroundCheck;
13224 mSupportsLeanbackOnly = supportsLeanbackOnly;
13225 mForceResizableActivities = forceResizable;
13226 mWindowManager.setForceResizableTasks(mForceResizableActivities);
13227 if (supportsMultiWindow || forceResizable) {
13228 mSupportsMultiWindow = true;
13229 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13230 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13232 mSupportsMultiWindow = false;
13233 mSupportsFreeformWindowManagement = false;
13234 mSupportsPictureInPicture = false;
13236 // This happens before any activities are started, so we can
13237 // change mConfiguration in-place.
13238 updateConfigurationLocked(configuration, null, true);
13239 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13240 "Initial config: " + mConfiguration);
13242 // Load resources only after the current configuration has been set.
13243 final Resources res = mContext.getResources();
13244 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13245 mThumbnailWidth = res.getDimensionPixelSize(
13246 com.android.internal.R.dimen.thumbnail_width);
13247 mThumbnailHeight = res.getDimensionPixelSize(
13248 com.android.internal.R.dimen.thumbnail_height);
13249 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13250 com.android.internal.R.string.config_defaultPictureInPictureBounds));
13251 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13252 com.android.internal.R.string.config_appsNotReportingCrashes));
13253 if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13254 mFullscreenThumbnailScale = (float) res
13255 .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13256 (float) mConfiguration.screenWidthDp;
13258 mFullscreenThumbnailScale = res.getFraction(
13259 com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13264 public boolean testIsSystemReady() {
13265 // no need to synchronize(this) just to read & return the value
13266 return mSystemReady;
13269 public void systemReady(final Runnable goingCallback) {
13270 synchronized(this) {
13271 if (mSystemReady) {
13272 // If we're done calling all the receivers, run the next "boot phase" passed in
13273 // by the SystemServer
13274 if (goingCallback != null) {
13275 goingCallback.run();
13280 mLocalDeviceIdleController
13281 = LocalServices.getService(DeviceIdleController.LocalService.class);
13283 // Make sure we have the current profile info, since it is needed for security checks.
13284 mUserController.onSystemReady();
13285 mRecentTasks.onSystemReadyLocked();
13286 mAppOpsService.systemReady();
13287 mSystemReady = true;
13290 ArrayList<ProcessRecord> procsToKill = null;
13291 synchronized(mPidsSelfLocked) {
13292 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13293 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13294 if (!isAllowedWhileBooting(proc.info)){
13295 if (procsToKill == null) {
13296 procsToKill = new ArrayList<ProcessRecord>();
13298 procsToKill.add(proc);
13303 synchronized(this) {
13304 if (procsToKill != null) {
13305 for (int i=procsToKill.size()-1; i>=0; i--) {
13306 ProcessRecord proc = procsToKill.get(i);
13307 Slog.i(TAG, "Removing system update proc: " + proc);
13308 removeProcessLocked(proc, true, false, "system update done");
13312 // Now that we have cleaned up any update processes, we
13313 // are ready to start launching real processes and know that
13314 // we won't trample on them any more.
13315 mProcessesReady = true;
13318 Slog.i(TAG, "System now ready");
13319 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13320 SystemClock.uptimeMillis());
13322 synchronized(this) {
13323 // Make sure we have no pre-ready processes sitting around.
13325 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13326 ResolveInfo ri = mContext.getPackageManager()
13327 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13329 CharSequence errorMsg = null;
13331 ActivityInfo ai = ri.activityInfo;
13332 ApplicationInfo app = ai.applicationInfo;
13333 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13334 mTopAction = Intent.ACTION_FACTORY_TEST;
13336 mTopComponent = new ComponentName(app.packageName,
13339 errorMsg = mContext.getResources().getText(
13340 com.android.internal.R.string.factorytest_not_system);
13343 errorMsg = mContext.getResources().getText(
13344 com.android.internal.R.string.factorytest_no_action);
13346 if (errorMsg != null) {
13349 mTopComponent = null;
13350 Message msg = Message.obtain();
13351 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13352 msg.getData().putCharSequence("msg", errorMsg);
13353 mUiHandler.sendMessage(msg);
13358 retrieveSettings();
13359 final int currentUserId;
13360 synchronized (this) {
13361 currentUserId = mUserController.getCurrentUserIdLocked();
13362 readGrantedUriPermissionsLocked();
13365 if (goingCallback != null) goingCallback.run();
13367 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13368 Integer.toString(currentUserId), currentUserId);
13369 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13370 Integer.toString(currentUserId), currentUserId);
13371 mSystemServiceManager.startUser(currentUserId);
13373 synchronized (this) {
13374 // Only start up encryption-aware persistent apps; once user is
13375 // unlocked we'll come back around and start unaware apps
13376 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13378 // Start up initial activity.
13380 // Enable home activity for system user, so that the system can always boot
13381 if (UserManager.isSplitSystemUser()) {
13382 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13384 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13385 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13386 UserHandle.USER_SYSTEM);
13387 } catch (RemoteException e) {
13388 throw e.rethrowAsRuntimeException();
13391 startHomeActivityLocked(currentUserId, "systemReady");
13394 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13395 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13396 + " data partition or your device will be unstable.");
13397 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13399 } catch (RemoteException e) {
13402 if (!Build.isBuildConsistent()) {
13403 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13404 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13407 long ident = Binder.clearCallingIdentity();
13409 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13410 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13411 | Intent.FLAG_RECEIVER_FOREGROUND);
13412 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13413 broadcastIntentLocked(null, null, intent,
13414 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13415 null, false, false, MY_PID, Process.SYSTEM_UID,
13417 intent = new Intent(Intent.ACTION_USER_STARTING);
13418 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13419 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13420 broadcastIntentLocked(null, null, intent,
13421 null, new IIntentReceiver.Stub() {
13423 public void performReceive(Intent intent, int resultCode, String data,
13424 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13425 throws RemoteException {
13428 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13429 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13430 } catch (Throwable t) {
13431 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13433 Binder.restoreCallingIdentity(ident);
13435 mStackSupervisor.resumeFocusedStackTopActivityLocked();
13436 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13440 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13441 synchronized (this) {
13442 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13446 void skipCurrentReceiverLocked(ProcessRecord app) {
13447 for (BroadcastQueue queue : mBroadcastQueues) {
13448 queue.skipCurrentReceiverLocked(app);
13453 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13454 * The application process will exit immediately after this call returns.
13455 * @param app object of the crashing app, null for the system server
13456 * @param crashInfo describing the exception
13458 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13459 ProcessRecord r = findAppProcess(app, "Crash");
13460 final String processName = app == null ? "system_server"
13461 : (r == null ? "unknown" : r.processName);
13463 handleApplicationCrashInner("crash", r, processName, crashInfo);
13466 /* Native crash reporting uses this inner version because it needs to be somewhat
13467 * decoupled from the AM-managed cleanup lifecycle
13469 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13470 ApplicationErrorReport.CrashInfo crashInfo) {
13471 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13472 UserHandle.getUserId(Binder.getCallingUid()), processName,
13473 r == null ? -1 : r.info.flags,
13474 crashInfo.exceptionClassName,
13475 crashInfo.exceptionMessage,
13476 crashInfo.throwFileName,
13477 crashInfo.throwLineNumber);
13479 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13481 mAppErrors.crashApplication(r, crashInfo);
13484 public void handleApplicationStrictModeViolation(
13487 StrictMode.ViolationInfo info) {
13488 ProcessRecord r = findAppProcess(app, "StrictMode");
13493 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13494 Integer stackFingerprint = info.hashCode();
13495 boolean logIt = true;
13496 synchronized (mAlreadyLoggedViolatedStacks) {
13497 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13499 // TODO: sub-sample into EventLog for these, with
13500 // the info.durationMillis? Then we'd get
13501 // the relative pain numbers, without logging all
13502 // the stack traces repeatedly. We'd want to do
13503 // likewise in the client code, which also does
13504 // dup suppression, before the Binder call.
13506 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13507 mAlreadyLoggedViolatedStacks.clear();
13509 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13513 logStrictModeViolationToDropBox(r, info);
13517 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13518 AppErrorResult result = new AppErrorResult();
13519 synchronized (this) {
13520 final long origId = Binder.clearCallingIdentity();
13522 Message msg = Message.obtain();
13523 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13524 HashMap<String, Object> data = new HashMap<String, Object>();
13525 data.put("result", result);
13526 data.put("app", r);
13527 data.put("violationMask", violationMask);
13528 data.put("info", info);
13530 mUiHandler.sendMessage(msg);
13532 Binder.restoreCallingIdentity(origId);
13534 int res = result.get();
13535 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13539 // Depending on the policy in effect, there could be a bunch of
13540 // these in quick succession so we try to batch these together to
13541 // minimize disk writes, number of dropbox entries, and maximize
13542 // compression, by having more fewer, larger records.
13543 private void logStrictModeViolationToDropBox(
13544 ProcessRecord process,
13545 StrictMode.ViolationInfo info) {
13546 if (info == null) {
13549 final boolean isSystemApp = process == null ||
13550 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13551 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13552 final String processName = process == null ? "unknown" : process.processName;
13553 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13554 final DropBoxManager dbox = (DropBoxManager)
13555 mContext.getSystemService(Context.DROPBOX_SERVICE);
13557 // Exit early if the dropbox isn't configured to accept this report type.
13558 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13560 boolean bufferWasEmpty;
13561 boolean needsFlush;
13562 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13563 synchronized (sb) {
13564 bufferWasEmpty = sb.length() == 0;
13565 appendDropBoxProcessHeaders(process, processName, sb);
13566 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13567 sb.append("System-App: ").append(isSystemApp).append("\n");
13568 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13569 if (info.violationNumThisLoop != 0) {
13570 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13572 if (info.numAnimationsRunning != 0) {
13573 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13575 if (info.broadcastIntentAction != null) {
13576 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13578 if (info.durationMillis != -1) {
13579 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13581 if (info.numInstances != -1) {
13582 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13584 if (info.tags != null) {
13585 for (String tag : info.tags) {
13586 sb.append("Span-Tag: ").append(tag).append("\n");
13590 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13591 sb.append(info.crashInfo.stackTrace);
13594 if (info.message != null) {
13595 sb.append(info.message);
13599 // Only buffer up to ~64k. Various logging bits truncate
13601 needsFlush = (sb.length() > 64 * 1024);
13604 // Flush immediately if the buffer's grown too large, or this
13605 // is a non-system app. Non-system apps are isolated with a
13606 // different tag & policy and not batched.
13608 // Batching is useful during internal testing with
13609 // StrictMode settings turned up high. Without batching,
13610 // thousands of separate files could be created on boot.
13611 if (!isSystemApp || needsFlush) {
13612 new Thread("Error dump: " + dropboxTag) {
13614 public void run() {
13616 synchronized (sb) {
13617 report = sb.toString();
13618 sb.delete(0, sb.length());
13621 if (report.length() != 0) {
13622 dbox.addText(dropboxTag, report);
13629 // System app batching:
13630 if (!bufferWasEmpty) {
13631 // An existing dropbox-writing thread is outstanding, so
13632 // we don't need to start it up. The existing thread will
13633 // catch the buffer appends we just did.
13637 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13638 // (After this point, we shouldn't access AMS internal data structures.)
13639 new Thread("Error dump: " + dropboxTag) {
13641 public void run() {
13642 // 5 second sleep to let stacks arrive and be batched together
13644 Thread.sleep(5000); // 5 seconds
13645 } catch (InterruptedException e) {}
13647 String errorReport;
13648 synchronized (mStrictModeBuffer) {
13649 errorReport = mStrictModeBuffer.toString();
13650 if (errorReport.length() == 0) {
13653 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13654 mStrictModeBuffer.trimToSize();
13656 dbox.addText(dropboxTag, errorReport);
13662 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13663 * @param app object of the crashing app, null for the system server
13664 * @param tag reported by the caller
13665 * @param system whether this wtf is coming from the system
13666 * @param crashInfo describing the context of the error
13667 * @return true if the process should exit immediately (WTF is fatal)
13669 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13670 final ApplicationErrorReport.CrashInfo crashInfo) {
13671 final int callingUid = Binder.getCallingUid();
13672 final int callingPid = Binder.getCallingPid();
13675 // If this is coming from the system, we could very well have low-level
13676 // system locks held, so we want to do this all asynchronously. And we
13677 // never want this to become fatal, so there is that too.
13678 mHandler.post(new Runnable() {
13679 @Override public void run() {
13680 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13686 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13689 if (r != null && r.pid != Process.myPid() &&
13690 Settings.Global.getInt(mContext.getContentResolver(),
13691 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13692 mAppErrors.crashApplication(r, crashInfo);
13699 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13700 final ApplicationErrorReport.CrashInfo crashInfo) {
13701 final ProcessRecord r = findAppProcess(app, "WTF");
13702 final String processName = app == null ? "system_server"
13703 : (r == null ? "unknown" : r.processName);
13705 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13706 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13708 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13714 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13715 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13717 private ProcessRecord findAppProcess(IBinder app, String reason) {
13722 synchronized (this) {
13723 final int NP = mProcessNames.getMap().size();
13724 for (int ip=0; ip<NP; ip++) {
13725 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13726 final int NA = apps.size();
13727 for (int ia=0; ia<NA; ia++) {
13728 ProcessRecord p = apps.valueAt(ia);
13729 if (p.thread != null && p.thread.asBinder() == app) {
13735 Slog.w(TAG, "Can't find mystery application for " + reason
13736 + " from pid=" + Binder.getCallingPid()
13737 + " uid=" + Binder.getCallingUid() + ": " + app);
13743 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13744 * to append various headers to the dropbox log text.
13746 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13747 StringBuilder sb) {
13748 // Watchdog thread ends up invoking this function (with
13749 // a null ProcessRecord) to add the stack file to dropbox.
13750 // Do not acquire a lock on this (am) in such cases, as it
13751 // could cause a potential deadlock, if and when watchdog
13752 // is invoked due to unavailability of lock on am and it
13753 // would prevent watchdog from killing system_server.
13754 if (process == null) {
13755 sb.append("Process: ").append(processName).append("\n");
13758 // Note: ProcessRecord 'process' is guarded by the service
13759 // instance. (notably process.pkgList, which could otherwise change
13760 // concurrently during execution of this method)
13761 synchronized (this) {
13762 sb.append("Process: ").append(processName).append("\n");
13763 int flags = process.info.flags;
13764 IPackageManager pm = AppGlobals.getPackageManager();
13765 sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13766 for (int ip=0; ip<process.pkgList.size(); ip++) {
13767 String pkg = process.pkgList.keyAt(ip);
13768 sb.append("Package: ").append(pkg);
13770 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13772 sb.append(" v").append(pi.versionCode);
13773 if (pi.versionName != null) {
13774 sb.append(" (").append(pi.versionName).append(")");
13777 } catch (RemoteException e) {
13778 Slog.e(TAG, "Error getting package info: " + pkg, e);
13785 private static String processClass(ProcessRecord process) {
13786 if (process == null || process.pid == MY_PID) {
13787 return "system_server";
13788 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13789 return "system_app";
13795 private volatile long mWtfClusterStart;
13796 private volatile int mWtfClusterCount;
13799 * Write a description of an error (crash, WTF, ANR) to the drop box.
13800 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13801 * @param process which caused the error, null means the system server
13802 * @param activity which triggered the error, null if unknown
13803 * @param parent activity related to the error, null if unknown
13804 * @param subject line related to the error, null if absent
13805 * @param report in long form describing the error, null if absent
13806 * @param dataFile text file to include in the report, null if none
13807 * @param crashInfo giving an application stack trace, null if absent
13809 public void addErrorToDropBox(String eventType,
13810 ProcessRecord process, String processName, ActivityRecord activity,
13811 ActivityRecord parent, String subject,
13812 final String report, final File dataFile,
13813 final ApplicationErrorReport.CrashInfo crashInfo) {
13814 // NOTE -- this must never acquire the ActivityManagerService lock,
13815 // otherwise the watchdog may be prevented from resetting the system.
13817 final String dropboxTag = processClass(process) + "_" + eventType;
13818 final DropBoxManager dbox = (DropBoxManager)
13819 mContext.getSystemService(Context.DROPBOX_SERVICE);
13821 // Exit early if the dropbox isn't configured to accept this report type.
13822 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13824 // Rate-limit how often we're willing to do the heavy lifting below to
13825 // collect and record logs; currently 5 logs per 10 second period.
13826 final long now = SystemClock.elapsedRealtime();
13827 if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13828 mWtfClusterStart = now;
13829 mWtfClusterCount = 1;
13831 if (mWtfClusterCount++ >= 5) return;
13834 final StringBuilder sb = new StringBuilder(1024);
13835 appendDropBoxProcessHeaders(process, processName, sb);
13836 if (process != null) {
13837 sb.append("Foreground: ")
13838 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13841 if (activity != null) {
13842 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13844 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13845 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13847 if (parent != null && parent != activity) {
13848 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13850 if (subject != null) {
13851 sb.append("Subject: ").append(subject).append("\n");
13853 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13854 if (Debug.isDebuggerConnected()) {
13855 sb.append("Debugger: Connected\n");
13859 // Do the rest in a worker thread to avoid blocking the caller on I/O
13860 // (After this point, we shouldn't access AMS internal data structures.)
13861 Thread worker = new Thread("Error dump: " + dropboxTag) {
13863 public void run() {
13864 if (report != null) {
13868 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13869 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13870 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13871 - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13873 if (dataFile != null && maxDataFileSize > 0) {
13875 sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13876 "\n\n[[TRUNCATED]]"));
13877 } catch (IOException e) {
13878 Slog.e(TAG, "Error reading " + dataFile, e);
13881 if (crashInfo != null && crashInfo.stackTrace != null) {
13882 sb.append(crashInfo.stackTrace);
13888 // Merge several logcat streams, and take the last N lines
13889 InputStreamReader input = null;
13891 java.lang.Process logcat = new ProcessBuilder(
13892 "/system/bin/timeout", "-k", "15s", "10s",
13893 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13894 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13895 .redirectErrorStream(true).start();
13897 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13898 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13899 input = new InputStreamReader(logcat.getInputStream());
13902 char[] buf = new char[8192];
13903 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13904 } catch (IOException e) {
13905 Slog.e(TAG, "Error running logcat", e);
13907 if (input != null) try { input.close(); } catch (IOException e) {}
13911 dbox.addText(dropboxTag, sb.toString());
13915 if (process == null) {
13916 // If process is null, we are being called from some internal code
13917 // and may be about to die -- run this synchronously.
13925 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13926 enforceNotIsolatedCaller("getProcessesInErrorState");
13927 // assume our apps are happy - lazy create the list
13928 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13930 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13931 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13932 int userId = UserHandle.getUserId(Binder.getCallingUid());
13934 synchronized (this) {
13936 // iterate across all processes
13937 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13938 ProcessRecord app = mLruProcesses.get(i);
13939 if (!allUsers && app.userId != userId) {
13942 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13943 // This one's in trouble, so we'll generate a report for it
13944 // crashes are higher priority (in case there's a crash *and* an anr)
13945 ActivityManager.ProcessErrorStateInfo report = null;
13946 if (app.crashing) {
13947 report = app.crashingReport;
13948 } else if (app.notResponding) {
13949 report = app.notRespondingReport;
13952 if (report != null) {
13953 if (errList == null) {
13954 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13956 errList.add(report);
13958 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13959 " crashing = " + app.crashing +
13960 " notResponding = " + app.notResponding);
13969 static int procStateToImportance(int procState, int memAdj,
13970 ActivityManager.RunningAppProcessInfo currApp) {
13971 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13972 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13973 currApp.lru = memAdj;
13980 private void fillInProcMemInfo(ProcessRecord app,
13981 ActivityManager.RunningAppProcessInfo outInfo) {
13982 outInfo.pid = app.pid;
13983 outInfo.uid = app.info.uid;
13984 if (mHeavyWeightProcess == app) {
13985 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13987 if (app.persistent) {
13988 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13990 if (app.activities.size() > 0) {
13991 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13993 outInfo.lastTrimLevel = app.trimMemoryLevel;
13994 int adj = app.curAdj;
13995 int procState = app.curProcState;
13996 outInfo.importance = procStateToImportance(procState, adj, outInfo);
13997 outInfo.importanceReasonCode = app.adjTypeCode;
13998 outInfo.processState = app.curProcState;
14002 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14003 enforceNotIsolatedCaller("getRunningAppProcesses");
14005 final int callingUid = Binder.getCallingUid();
14007 // Lazy instantiation of list
14008 List<ActivityManager.RunningAppProcessInfo> runList = null;
14009 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14010 callingUid) == PackageManager.PERMISSION_GRANTED;
14011 final int userId = UserHandle.getUserId(callingUid);
14012 final boolean allUids = isGetTasksAllowed(
14013 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14015 synchronized (this) {
14016 // Iterate across all processes
14017 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14018 ProcessRecord app = mLruProcesses.get(i);
14019 if ((!allUsers && app.userId != userId)
14020 || (!allUids && app.uid != callingUid)) {
14023 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14024 // Generate process state info for running application
14025 ActivityManager.RunningAppProcessInfo currApp =
14026 new ActivityManager.RunningAppProcessInfo(app.processName,
14027 app.pid, app.getPackageList());
14028 fillInProcMemInfo(app, currApp);
14029 if (app.adjSource instanceof ProcessRecord) {
14030 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14031 currApp.importanceReasonImportance =
14032 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14033 app.adjSourceProcState);
14034 } else if (app.adjSource instanceof ActivityRecord) {
14035 ActivityRecord r = (ActivityRecord)app.adjSource;
14036 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14038 if (app.adjTarget instanceof ComponentName) {
14039 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14041 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14042 // + " lru=" + currApp.lru);
14043 if (runList == null) {
14044 runList = new ArrayList<>();
14046 runList.add(currApp);
14054 public List<ApplicationInfo> getRunningExternalApplications() {
14055 enforceNotIsolatedCaller("getRunningExternalApplications");
14056 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14057 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14058 if (runningApps != null && runningApps.size() > 0) {
14059 Set<String> extList = new HashSet<String>();
14060 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14061 if (app.pkgList != null) {
14062 for (String pkg : app.pkgList) {
14067 IPackageManager pm = AppGlobals.getPackageManager();
14068 for (String pkg : extList) {
14070 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14071 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14074 } catch (RemoteException e) {
14082 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14083 enforceNotIsolatedCaller("getMyMemoryState");
14084 synchronized (this) {
14085 ProcessRecord proc;
14086 synchronized (mPidsSelfLocked) {
14087 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14089 fillInProcMemInfo(proc, outInfo);
14094 public int getMemoryTrimLevel() {
14095 enforceNotIsolatedCaller("getMyMemoryState");
14096 synchronized (this) {
14097 return mLastMemoryLevel;
14102 public void onShellCommand(FileDescriptor in, FileDescriptor out,
14103 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14104 (new ActivityManagerShellCommand(this, false)).exec(
14105 this, in, out, err, args, resultReceiver);
14109 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14110 if (checkCallingPermission(android.Manifest.permission.DUMP)
14111 != PackageManager.PERMISSION_GRANTED) {
14112 pw.println("Permission Denial: can't dump ActivityManager from from pid="
14113 + Binder.getCallingPid()
14114 + ", uid=" + Binder.getCallingUid()
14115 + " without permission "
14116 + android.Manifest.permission.DUMP);
14120 boolean dumpAll = false;
14121 boolean dumpClient = false;
14122 boolean dumpCheckin = false;
14123 boolean dumpCheckinFormat = false;
14124 String dumpPackage = null;
14127 while (opti < args.length) {
14128 String opt = args[opti];
14129 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14133 if ("-a".equals(opt)) {
14135 } else if ("-c".equals(opt)) {
14137 } else if ("-p".equals(opt)) {
14138 if (opti < args.length) {
14139 dumpPackage = args[opti];
14142 pw.println("Error: -p option requires package argument");
14146 } else if ("--checkin".equals(opt)) {
14147 dumpCheckin = dumpCheckinFormat = true;
14148 } else if ("-C".equals(opt)) {
14149 dumpCheckinFormat = true;
14150 } else if ("-h".equals(opt)) {
14151 ActivityManagerShellCommand.dumpHelp(pw, true);
14154 pw.println("Unknown argument: " + opt + "; use -h for help");
14158 long origId = Binder.clearCallingIdentity();
14159 boolean more = false;
14160 // Is the caller requesting to dump a particular piece of data?
14161 if (opti < args.length) {
14162 String cmd = args[opti];
14164 if ("activities".equals(cmd) || "a".equals(cmd)) {
14165 synchronized (this) {
14166 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14168 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14169 synchronized (this) {
14170 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14172 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14175 if (opti >= args.length) {
14177 newArgs = EMPTY_STRING_ARRAY;
14179 dumpPackage = args[opti];
14181 newArgs = new String[args.length - opti];
14182 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14183 args.length - opti);
14185 synchronized (this) {
14186 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14188 } else if ("broadcast-stats".equals(cmd)) {
14191 if (opti >= args.length) {
14193 newArgs = EMPTY_STRING_ARRAY;
14195 dumpPackage = args[opti];
14197 newArgs = new String[args.length - opti];
14198 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14199 args.length - opti);
14201 synchronized (this) {
14202 if (dumpCheckinFormat) {
14203 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14206 dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14209 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14212 if (opti >= args.length) {
14214 newArgs = EMPTY_STRING_ARRAY;
14216 dumpPackage = args[opti];
14218 newArgs = new String[args.length - opti];
14219 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14220 args.length - opti);
14222 synchronized (this) {
14223 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14225 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14228 if (opti >= args.length) {
14230 newArgs = EMPTY_STRING_ARRAY;
14232 dumpPackage = args[opti];
14234 newArgs = new String[args.length - opti];
14235 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14236 args.length - opti);
14238 synchronized (this) {
14239 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14241 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14242 synchronized (this) {
14243 dumpOomLocked(fd, pw, args, opti, true);
14245 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14246 synchronized (this) {
14247 dumpPermissionsLocked(fd, pw, args, opti, true, null);
14249 } else if ("provider".equals(cmd)) {
14252 if (opti >= args.length) {
14254 newArgs = EMPTY_STRING_ARRAY;
14258 newArgs = new String[args.length - opti];
14259 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14261 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14262 pw.println("No providers match: " + name);
14263 pw.println("Use -h for help.");
14265 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14266 synchronized (this) {
14267 dumpProvidersLocked(fd, pw, args, opti, true, null);
14269 } else if ("service".equals(cmd)) {
14272 if (opti >= args.length) {
14274 newArgs = EMPTY_STRING_ARRAY;
14278 newArgs = new String[args.length - opti];
14279 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14280 args.length - opti);
14282 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14283 pw.println("No services match: " + name);
14284 pw.println("Use -h for help.");
14286 } else if ("package".equals(cmd)) {
14288 if (opti >= args.length) {
14289 pw.println("package: no package name specified");
14290 pw.println("Use -h for help.");
14292 dumpPackage = args[opti];
14294 newArgs = new String[args.length - opti];
14295 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14296 args.length - opti);
14301 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14302 synchronized (this) {
14303 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14305 } else if ("services".equals(cmd) || "s".equals(cmd)) {
14307 ActiveServices.ServiceDumper dumper;
14308 synchronized (this) {
14309 dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14312 dumper.dumpWithClient();
14314 synchronized (this) {
14315 mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14316 dumpPackage).dumpLocked();
14319 } else if ("locks".equals(cmd)) {
14320 LockGuard.dump(fd, pw, args);
14322 // Dumping a single activity?
14323 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14324 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14325 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14327 pw.println("Bad activity command, or no activities match: " + cmd);
14328 pw.println("Use -h for help.");
14333 Binder.restoreCallingIdentity(origId);
14338 // No piece of data specified, dump everything.
14339 if (dumpCheckinFormat) {
14340 dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14341 } else if (dumpClient) {
14342 ActiveServices.ServiceDumper sdumper;
14343 synchronized (this) {
14344 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14347 pw.println("-------------------------------------------------------------------------------");
14349 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14352 pw.println("-------------------------------------------------------------------------------");
14354 if (dumpAll || dumpPackage != null) {
14355 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14358 pw.println("-------------------------------------------------------------------------------");
14361 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14364 pw.println("-------------------------------------------------------------------------------");
14366 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14369 pw.println("-------------------------------------------------------------------------------");
14371 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14374 sdumper.dumpWithClient();
14376 synchronized (this) {
14378 pw.println("-------------------------------------------------------------------------------");
14380 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14383 pw.println("-------------------------------------------------------------------------------");
14385 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14386 if (mAssociations.size() > 0) {
14389 pw.println("-------------------------------------------------------------------------------");
14391 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14395 pw.println("-------------------------------------------------------------------------------");
14397 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14401 synchronized (this) {
14402 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14405 pw.println("-------------------------------------------------------------------------------");
14407 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14410 pw.println("-------------------------------------------------------------------------------");
14412 if (dumpAll || dumpPackage != null) {
14413 dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14416 pw.println("-------------------------------------------------------------------------------");
14419 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14422 pw.println("-------------------------------------------------------------------------------");
14424 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14427 pw.println("-------------------------------------------------------------------------------");
14429 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14433 pw.println("-------------------------------------------------------------------------------");
14435 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14438 pw.println("-------------------------------------------------------------------------------");
14440 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14441 if (mAssociations.size() > 0) {
14444 pw.println("-------------------------------------------------------------------------------");
14446 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14450 pw.println("-------------------------------------------------------------------------------");
14452 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14455 Binder.restoreCallingIdentity(origId);
14458 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14459 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14460 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14462 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14464 boolean needSep = printedAnything;
14466 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14467 dumpPackage, needSep, " mFocusedActivity: ");
14469 printedAnything = true;
14473 if (dumpPackage == null) {
14478 printedAnything = true;
14479 mStackSupervisor.dump(pw, " ");
14482 if (!printedAnything) {
14483 pw.println(" (nothing)");
14487 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14488 int opti, boolean dumpAll, String dumpPackage) {
14489 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14491 boolean printedAnything = false;
14493 if (mRecentTasks != null && mRecentTasks.size() > 0) {
14494 boolean printedHeader = false;
14496 final int N = mRecentTasks.size();
14497 for (int i=0; i<N; i++) {
14498 TaskRecord tr = mRecentTasks.get(i);
14499 if (dumpPackage != null) {
14500 if (tr.realActivity == null ||
14501 !dumpPackage.equals(tr.realActivity)) {
14505 if (!printedHeader) {
14506 pw.println(" Recent tasks:");
14507 printedHeader = true;
14508 printedAnything = true;
14510 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
14513 mRecentTasks.get(i).dump(pw, " ");
14518 if (!printedAnything) {
14519 pw.println(" (nothing)");
14523 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14524 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14525 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14528 if (dumpPackage != null) {
14529 IPackageManager pm = AppGlobals.getPackageManager();
14531 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14532 } catch (RemoteException e) {
14536 boolean printedAnything = false;
14538 final long now = SystemClock.uptimeMillis();
14540 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14541 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14542 = mAssociations.valueAt(i1);
14543 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14544 SparseArray<ArrayMap<String, Association>> sourceUids
14545 = targetComponents.valueAt(i2);
14546 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14547 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14548 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14549 Association ass = sourceProcesses.valueAt(i4);
14550 if (dumpPackage != null) {
14551 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14552 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14556 printedAnything = true;
14558 pw.print(ass.mTargetProcess);
14560 UserHandle.formatUid(pw, ass.mTargetUid);
14562 pw.print(ass.mSourceProcess);
14564 UserHandle.formatUid(pw, ass.mSourceUid);
14567 pw.print(ass.mTargetComponent.flattenToShortString());
14570 long dur = ass.mTime;
14571 if (ass.mNesting > 0) {
14572 dur += now - ass.mStartTime;
14574 TimeUtils.formatDuration(dur, pw);
14576 pw.print(ass.mCount);
14577 pw.print(" times)");
14579 for (int i=0; i<ass.mStateTimes.length; i++) {
14580 long amt = ass.mStateTimes[i];
14581 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14582 amt += now - ass.mLastStateUptime;
14586 pw.print(ProcessList.makeProcStateString(
14587 i + ActivityManager.MIN_PROCESS_STATE));
14589 TimeUtils.formatDuration(amt, pw);
14590 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14596 if (ass.mNesting > 0) {
14597 pw.print(" Currently active: ");
14598 TimeUtils.formatDuration(now - ass.mStartTime, pw);
14607 if (!printedAnything) {
14608 pw.println(" (nothing)");
14612 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14613 String header, boolean needSep) {
14614 boolean printed = false;
14615 int whichAppId = -1;
14616 if (dumpPackage != null) {
14618 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14620 whichAppId = UserHandle.getAppId(info.uid);
14621 } catch (NameNotFoundException e) {
14622 e.printStackTrace();
14625 for (int i=0; i<uids.size(); i++) {
14626 UidRecord uidRec = uids.valueAt(i);
14627 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14636 pw.println(header);
14639 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14640 pw.print(": "); pw.println(uidRec);
14645 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14646 int opti, boolean dumpAll, String dumpPackage) {
14647 boolean needSep = false;
14648 boolean printedAnything = false;
14651 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14654 final int NP = mProcessNames.getMap().size();
14655 for (int ip=0; ip<NP; ip++) {
14656 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14657 final int NA = procs.size();
14658 for (int ia=0; ia<NA; ia++) {
14659 ProcessRecord r = procs.valueAt(ia);
14660 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14664 pw.println(" All known processes:");
14666 printedAnything = true;
14668 pw.print(r.persistent ? " *PERS*" : " *APP*");
14669 pw.print(" UID "); pw.print(procs.keyAt(ia));
14670 pw.print(" "); pw.println(r);
14672 if (r.persistent) {
14679 if (mIsolatedProcesses.size() > 0) {
14680 boolean printed = false;
14681 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14682 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14683 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14690 pw.println(" Isolated process list (sorted by uid):");
14691 printedAnything = true;
14695 pw.println(String.format("%sIsolated #%2d: %s",
14696 " ", i, r.toString()));
14700 if (mActiveUids.size() > 0) {
14701 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14702 printedAnything = needSep = true;
14705 if (mValidateUids.size() > 0) {
14706 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14707 printedAnything = needSep = true;
14711 if (mLruProcesses.size() > 0) {
14715 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14716 pw.print(" total, non-act at ");
14717 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14718 pw.print(", non-svc at ");
14719 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14721 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14723 printedAnything = true;
14726 if (dumpAll || dumpPackage != null) {
14727 synchronized (mPidsSelfLocked) {
14728 boolean printed = false;
14729 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14730 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14731 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14735 if (needSep) pw.println();
14737 pw.println(" PID mappings:");
14739 printedAnything = true;
14741 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14742 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14747 if (mForegroundProcesses.size() > 0) {
14748 synchronized (mPidsSelfLocked) {
14749 boolean printed = false;
14750 for (int i=0; i<mForegroundProcesses.size(); i++) {
14751 ProcessRecord r = mPidsSelfLocked.get(
14752 mForegroundProcesses.valueAt(i).pid);
14753 if (dumpPackage != null && (r == null
14754 || !r.pkgList.containsKey(dumpPackage))) {
14758 if (needSep) pw.println();
14760 pw.println(" Foreground Processes:");
14762 printedAnything = true;
14764 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14765 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14770 if (mPersistentStartingProcesses.size() > 0) {
14771 if (needSep) pw.println();
14773 printedAnything = true;
14774 pw.println(" Persisent processes that are starting:");
14775 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14776 "Starting Norm", "Restarting PERS", dumpPackage);
14779 if (mRemovedProcesses.size() > 0) {
14780 if (needSep) pw.println();
14782 printedAnything = true;
14783 pw.println(" Processes that are being removed:");
14784 dumpProcessList(pw, this, mRemovedProcesses, " ",
14785 "Removed Norm", "Removed PERS", dumpPackage);
14788 if (mProcessesOnHold.size() > 0) {
14789 if (needSep) pw.println();
14791 printedAnything = true;
14792 pw.println(" Processes that are on old until the system is ready:");
14793 dumpProcessList(pw, this, mProcessesOnHold, " ",
14794 "OnHold Norm", "OnHold PERS", dumpPackage);
14797 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14799 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14801 printedAnything = true;
14804 if (dumpPackage == null) {
14807 mUserController.dump(pw, dumpAll);
14809 if (mHomeProcess != null && (dumpPackage == null
14810 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14815 pw.println(" mHomeProcess: " + mHomeProcess);
14817 if (mPreviousProcess != null && (dumpPackage == null
14818 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14823 pw.println(" mPreviousProcess: " + mPreviousProcess);
14826 StringBuilder sb = new StringBuilder(128);
14827 sb.append(" mPreviousProcessVisibleTime: ");
14828 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14831 if (mHeavyWeightProcess != null && (dumpPackage == null
14832 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14837 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14839 if (dumpPackage == null) {
14840 pw.println(" mConfiguration: " + mConfiguration);
14843 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14844 if (mCompatModePackages.getPackages().size() > 0) {
14845 boolean printed = false;
14846 for (Map.Entry<String, Integer> entry
14847 : mCompatModePackages.getPackages().entrySet()) {
14848 String pkg = entry.getKey();
14849 int mode = entry.getValue();
14850 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14854 pw.println(" mScreenCompatPackages:");
14857 pw.print(" "); pw.print(pkg); pw.print(": ");
14858 pw.print(mode); pw.println();
14862 if (dumpPackage == null) {
14863 pw.println(" mWakefulness="
14864 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14865 pw.println(" mSleepTokens=" + mSleepTokens);
14866 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14867 + lockScreenShownToString());
14868 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14869 if (mRunningVoice != null) {
14870 pw.println(" mRunningVoice=" + mRunningVoice);
14871 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14874 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14875 || mOrigWaitForDebugger) {
14876 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14877 || dumpPackage.equals(mOrigDebugApp)) {
14882 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14883 + " mDebugTransient=" + mDebugTransient
14884 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14887 if (mCurAppTimeTracker != null) {
14888 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14890 if (mMemWatchProcesses.getMap().size() > 0) {
14891 pw.println(" Mem watch processes:");
14892 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14893 = mMemWatchProcesses.getMap();
14894 for (int i=0; i<procs.size(); i++) {
14895 final String proc = procs.keyAt(i);
14896 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14897 for (int j=0; j<uids.size(); j++) {
14902 StringBuilder sb = new StringBuilder();
14903 sb.append(" ").append(proc).append('/');
14904 UserHandle.formatUid(sb, uids.keyAt(j));
14905 Pair<Long, String> val = uids.valueAt(j);
14906 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14907 if (val.second != null) {
14908 sb.append(", report to ").append(val.second);
14910 pw.println(sb.toString());
14913 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14914 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14915 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14916 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14918 if (mTrackAllocationApp != null) {
14919 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14924 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14927 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14928 || mProfileFd != null) {
14929 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14934 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14935 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14936 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14937 + mAutoStopProfiler);
14938 pw.println(" mProfileType=" + mProfileType);
14941 if (mNativeDebuggingApp != null) {
14942 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14947 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14950 if (dumpPackage == null) {
14951 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14952 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14953 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14955 if (mController != null) {
14956 pw.println(" mController=" + mController
14957 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14960 pw.println(" Total persistent processes: " + numPers);
14961 pw.println(" mProcessesReady=" + mProcessesReady
14962 + " mSystemReady=" + mSystemReady
14963 + " mBooted=" + mBooted
14964 + " mFactoryTest=" + mFactoryTest);
14965 pw.println(" mBooting=" + mBooting
14966 + " mCallFinishBooting=" + mCallFinishBooting
14967 + " mBootAnimationComplete=" + mBootAnimationComplete);
14968 pw.print(" mLastPowerCheckRealtime=");
14969 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14971 pw.print(" mLastPowerCheckUptime=");
14972 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14974 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14975 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14976 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14977 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
14978 + " (" + mLruProcesses.size() + " total)"
14979 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14980 + " mNumServiceProcs=" + mNumServiceProcs
14981 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14982 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
14983 + " mLastMemoryLevel=" + mLastMemoryLevel
14984 + " mLastNumProcesses=" + mLastNumProcesses);
14985 long now = SystemClock.uptimeMillis();
14986 pw.print(" mLastIdleTime=");
14987 TimeUtils.formatDuration(now, mLastIdleTime, pw);
14988 pw.print(" mLowRamSinceLastIdle=");
14989 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14994 if (!printedAnything) {
14995 pw.println(" (nothing)");
14999 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15000 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15001 if (mProcessesToGc.size() > 0) {
15002 boolean printed = false;
15003 long now = SystemClock.uptimeMillis();
15004 for (int i=0; i<mProcessesToGc.size(); i++) {
15005 ProcessRecord proc = mProcessesToGc.get(i);
15006 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15010 if (needSep) pw.println();
15012 pw.println(" Processes that are waiting to GC:");
15015 pw.print(" Process "); pw.println(proc);
15016 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
15017 pw.print(", last gced=");
15018 pw.print(now-proc.lastRequestedGc);
15019 pw.print(" ms ago, last lowMem=");
15020 pw.print(now-proc.lastLowMemory);
15021 pw.println(" ms ago");
15028 void printOomLevel(PrintWriter pw, String name, int adj) {
15032 if (adj < 10) pw.print(' ');
15034 if (adj > -10) pw.print(' ');
15040 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15044 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15045 int opti, boolean dumpAll) {
15046 boolean needSep = false;
15048 if (mLruProcesses.size() > 0) {
15049 if (needSep) pw.println();
15051 pw.println(" OOM levels:");
15052 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15053 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15054 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15055 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15056 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15057 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15058 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15059 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15060 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15061 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15062 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15063 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15064 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15065 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15067 if (needSep) pw.println();
15068 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
15069 pw.print(" total, non-act at ");
15070 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15071 pw.print(", non-svc at ");
15072 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15074 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
15078 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15081 pw.println(" mHomeProcess: " + mHomeProcess);
15082 pw.println(" mPreviousProcess: " + mPreviousProcess);
15083 if (mHeavyWeightProcess != null) {
15084 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
15091 * There are three ways to call this:
15092 * - no provider specified: dump all the providers
15093 * - a flattened component name that matched an existing provider was specified as the
15094 * first arg: dump that one provider
15095 * - the first arg isn't the flattened component name of an existing provider:
15096 * dump all providers whose component contains the first arg as a substring
15098 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15099 int opti, boolean dumpAll) {
15100 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15103 static class ItemMatcher {
15104 ArrayList<ComponentName> components;
15105 ArrayList<String> strings;
15106 ArrayList<Integer> objects;
15113 void build(String name) {
15114 ComponentName componentName = ComponentName.unflattenFromString(name);
15115 if (componentName != null) {
15116 if (components == null) {
15117 components = new ArrayList<ComponentName>();
15119 components.add(componentName);
15123 // Not a '/' separated full component name; maybe an object ID?
15125 objectId = Integer.parseInt(name, 16);
15126 if (objects == null) {
15127 objects = new ArrayList<Integer>();
15129 objects.add(objectId);
15131 } catch (RuntimeException e) {
15132 // Not an integer; just do string match.
15133 if (strings == null) {
15134 strings = new ArrayList<String>();
15142 int build(String[] args, int opti) {
15143 for (; opti<args.length; opti++) {
15144 String name = args[opti];
15145 if ("--".equals(name)) {
15153 boolean match(Object object, ComponentName comp) {
15157 if (components != null) {
15158 for (int i=0; i<components.size(); i++) {
15159 if (components.get(i).equals(comp)) {
15164 if (objects != null) {
15165 for (int i=0; i<objects.size(); i++) {
15166 if (System.identityHashCode(object) == objects.get(i)) {
15171 if (strings != null) {
15172 String flat = comp.flattenToString();
15173 for (int i=0; i<strings.size(); i++) {
15174 if (flat.contains(strings.get(i))) {
15184 * There are three things that cmd can be:
15185 * - a flattened component name that matches an existing activity
15186 * - the cmd arg isn't the flattened component name of an existing activity:
15187 * dump all activity whose component contains the cmd as a substring
15188 * - A hex number of the ActivityRecord object instance.
15190 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15191 int opti, boolean dumpAll) {
15192 ArrayList<ActivityRecord> activities;
15194 synchronized (this) {
15195 activities = mStackSupervisor.getDumpActivitiesLocked(name);
15198 if (activities.size() <= 0) {
15202 String[] newArgs = new String[args.length - opti];
15203 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15205 TaskRecord lastTask = null;
15206 boolean needSep = false;
15207 for (int i=activities.size()-1; i>=0; i--) {
15208 ActivityRecord r = activities.get(i);
15213 synchronized (this) {
15214 if (lastTask != r.task) {
15216 pw.print("TASK "); pw.print(lastTask.affinity);
15217 pw.print(" id="); pw.println(lastTask.taskId);
15219 lastTask.dump(pw, " ");
15223 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
15229 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15230 * there is a thread associated with the activity.
15232 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15233 final ActivityRecord r, String[] args, boolean dumpAll) {
15234 String innerPrefix = prefix + " ";
15235 synchronized (this) {
15236 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15237 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15239 if (r.app != null) pw.println(r.app.pid);
15240 else pw.println("(not running)");
15242 r.dump(pw, innerPrefix);
15245 if (r.app != null && r.app.thread != null) {
15246 // flush anything that is already in the PrintWriter since the thread is going
15247 // to write to the file descriptor directly
15250 TransferPipe tp = new TransferPipe();
15252 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15253 r.appToken, innerPrefix, args);
15258 } catch (IOException e) {
15259 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15260 } catch (RemoteException e) {
15261 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15266 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15267 int opti, boolean dumpAll, String dumpPackage) {
15268 boolean needSep = false;
15269 boolean onlyHistory = false;
15270 boolean printedAnything = false;
15272 if ("history".equals(dumpPackage)) {
15273 if (opti < args.length && "-s".equals(args[opti])) {
15276 onlyHistory = true;
15277 dumpPackage = null;
15280 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15281 if (!onlyHistory && dumpAll) {
15282 if (mRegisteredReceivers.size() > 0) {
15283 boolean printed = false;
15284 Iterator it = mRegisteredReceivers.values().iterator();
15285 while (it.hasNext()) {
15286 ReceiverList r = (ReceiverList)it.next();
15287 if (dumpPackage != null && (r.app == null ||
15288 !dumpPackage.equals(r.app.info.packageName))) {
15292 pw.println(" Registered Receivers:");
15295 printedAnything = true;
15297 pw.print(" * "); pw.println(r);
15302 if (mReceiverResolver.dump(pw, needSep ?
15303 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
15304 " ", dumpPackage, false, false)) {
15306 printedAnything = true;
15310 for (BroadcastQueue q : mBroadcastQueues) {
15311 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15312 printedAnything |= needSep;
15317 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15318 for (int user=0; user<mStickyBroadcasts.size(); user++) {
15323 printedAnything = true;
15324 pw.print(" Sticky broadcasts for user ");
15325 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15326 StringBuilder sb = new StringBuilder(128);
15327 for (Map.Entry<String, ArrayList<Intent>> ent
15328 : mStickyBroadcasts.valueAt(user).entrySet()) {
15329 pw.print(" * Sticky action "); pw.print(ent.getKey());
15332 ArrayList<Intent> intents = ent.getValue();
15333 final int N = intents.size();
15334 for (int i=0; i<N; i++) {
15336 sb.append(" Intent: ");
15337 intents.get(i).toShortString(sb, false, true, false, false);
15338 pw.println(sb.toString());
15339 Bundle bundle = intents.get(i).getExtras();
15340 if (bundle != null) {
15342 pw.println(bundle.toString());
15352 if (!onlyHistory && dumpAll) {
15354 for (BroadcastQueue queue : mBroadcastQueues) {
15355 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
15356 + queue.mBroadcastsScheduled);
15358 pw.println(" mHandler:");
15359 mHandler.dump(new PrintWriterPrinter(pw), " ");
15361 printedAnything = true;
15364 if (!printedAnything) {
15365 pw.println(" (nothing)");
15369 void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15370 int opti, boolean dumpAll, String dumpPackage) {
15371 if (mCurBroadcastStats == null) {
15375 pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15376 final long now = SystemClock.elapsedRealtime();
15377 if (mLastBroadcastStats != null) {
15378 pw.print(" Last stats (from ");
15379 TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15381 TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15383 TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15384 - mLastBroadcastStats.mStartUptime, pw);
15385 pw.println(" uptime):");
15386 if (!mLastBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15387 pw.println(" (nothing)");
15391 pw.print(" Current stats (from ");
15392 TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15393 pw.print(" to now, ");
15394 TimeUtils.formatDuration(SystemClock.uptimeMillis()
15395 - mCurBroadcastStats.mStartUptime, pw);
15396 pw.println(" uptime):");
15397 if (!mCurBroadcastStats.dumpStats(pw, " ", dumpPackage)) {
15398 pw.println(" (nothing)");
15402 void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15403 int opti, boolean fullCheckin, String dumpPackage) {
15404 if (mCurBroadcastStats == null) {
15408 if (mLastBroadcastStats != null) {
15409 mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15411 mLastBroadcastStats = null;
15415 mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15417 mCurBroadcastStats = null;
15421 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15422 int opti, boolean dumpAll, String dumpPackage) {
15424 boolean printedAnything = false;
15426 ItemMatcher matcher = new ItemMatcher();
15427 matcher.build(args, opti);
15429 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15431 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15432 printedAnything |= needSep;
15434 if (mLaunchingProviders.size() > 0) {
15435 boolean printed = false;
15436 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15437 ContentProviderRecord r = mLaunchingProviders.get(i);
15438 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15442 if (needSep) pw.println();
15444 pw.println(" Launching content providers:");
15446 printedAnything = true;
15448 pw.print(" Launching #"); pw.print(i); pw.print(": ");
15453 if (!printedAnything) {
15454 pw.println(" (nothing)");
15458 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15459 int opti, boolean dumpAll, String dumpPackage) {
15460 boolean needSep = false;
15461 boolean printedAnything = false;
15463 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15465 if (mGrantedUriPermissions.size() > 0) {
15466 boolean printed = false;
15468 if (dumpPackage != null) {
15470 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15471 MATCH_UNINSTALLED_PACKAGES, 0);
15472 } catch (NameNotFoundException e) {
15476 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15477 int uid = mGrantedUriPermissions.keyAt(i);
15478 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15481 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15483 if (needSep) pw.println();
15485 pw.println(" Granted Uri Permissions:");
15487 printedAnything = true;
15489 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
15490 for (UriPermission perm : perms.values()) {
15491 pw.print(" "); pw.println(perm);
15493 perm.dump(pw, " ");
15499 if (!printedAnything) {
15500 pw.println(" (nothing)");
15504 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15505 int opti, boolean dumpAll, String dumpPackage) {
15506 boolean printed = false;
15508 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15510 if (mIntentSenderRecords.size() > 0) {
15511 Iterator<WeakReference<PendingIntentRecord>> it
15512 = mIntentSenderRecords.values().iterator();
15513 while (it.hasNext()) {
15514 WeakReference<PendingIntentRecord> ref = it.next();
15515 PendingIntentRecord rec = ref != null ? ref.get(): null;
15516 if (dumpPackage != null && (rec == null
15517 || !dumpPackage.equals(rec.key.packageName))) {
15522 pw.print(" * "); pw.println(rec);
15527 pw.print(" * "); pw.println(ref);
15533 pw.println(" (nothing)");
15537 private static final int dumpProcessList(PrintWriter pw,
15538 ActivityManagerService service, List list,
15539 String prefix, String normalLabel, String persistentLabel,
15540 String dumpPackage) {
15542 final int N = list.size()-1;
15543 for (int i=N; i>=0; i--) {
15544 ProcessRecord r = (ProcessRecord)list.get(i);
15545 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15548 pw.println(String.format("%s%s #%2d: %s",
15549 prefix, (r.persistent ? persistentLabel : normalLabel),
15551 if (r.persistent) {
15558 private static final boolean dumpProcessOomList(PrintWriter pw,
15559 ActivityManagerService service, List<ProcessRecord> origList,
15560 String prefix, String normalLabel, String persistentLabel,
15561 boolean inclDetails, String dumpPackage) {
15563 ArrayList<Pair<ProcessRecord, Integer>> list
15564 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15565 for (int i=0; i<origList.size(); i++) {
15566 ProcessRecord r = origList.get(i);
15567 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15570 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15573 if (list.size() <= 0) {
15577 Comparator<Pair<ProcessRecord, Integer>> comparator
15578 = new Comparator<Pair<ProcessRecord, Integer>>() {
15580 public int compare(Pair<ProcessRecord, Integer> object1,
15581 Pair<ProcessRecord, Integer> object2) {
15582 if (object1.first.setAdj != object2.first.setAdj) {
15583 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15585 if (object1.first.setProcState != object2.first.setProcState) {
15586 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15588 if (object1.second.intValue() != object2.second.intValue()) {
15589 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15595 Collections.sort(list, comparator);
15597 final long curRealtime = SystemClock.elapsedRealtime();
15598 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15599 final long curUptime = SystemClock.uptimeMillis();
15600 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15602 for (int i=list.size()-1; i>=0; i--) {
15603 ProcessRecord r = list.get(i).first;
15604 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15606 switch (r.setSchedGroup) {
15607 case ProcessList.SCHED_GROUP_BACKGROUND:
15610 case ProcessList.SCHED_GROUP_DEFAULT:
15613 case ProcessList.SCHED_GROUP_TOP_APP:
15621 if (r.foregroundActivities) {
15623 } else if (r.foregroundServices) {
15628 String procState = ProcessList.makeProcStateString(r.curProcState);
15630 pw.print(r.persistent ? persistentLabel : normalLabel);
15632 int num = (origList.size()-1)-list.get(i).second;
15633 if (num < 10) pw.print(' ');
15638 pw.print(schedGroup);
15640 pw.print(foreground);
15642 pw.print(procState);
15644 if (r.trimMemoryLevel < 10) pw.print(' ');
15645 pw.print(r.trimMemoryLevel);
15647 pw.print(r.toShortString());
15649 pw.print(r.adjType);
15651 if (r.adjSource != null || r.adjTarget != null) {
15654 if (r.adjTarget instanceof ComponentName) {
15655 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15656 } else if (r.adjTarget != null) {
15657 pw.print(r.adjTarget.toString());
15659 pw.print("{null}");
15662 if (r.adjSource instanceof ProcessRecord) {
15664 pw.print(((ProcessRecord)r.adjSource).toShortString());
15666 } else if (r.adjSource != null) {
15667 pw.println(r.adjSource.toString());
15669 pw.println("{null}");
15675 pw.print("oom: max="); pw.print(r.maxAdj);
15676 pw.print(" curRaw="); pw.print(r.curRawAdj);
15677 pw.print(" setRaw="); pw.print(r.setRawAdj);
15678 pw.print(" cur="); pw.print(r.curAdj);
15679 pw.print(" set="); pw.println(r.setAdj);
15682 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15683 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15684 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15685 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15686 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15690 pw.print("cached="); pw.print(r.cached);
15691 pw.print(" empty="); pw.print(r.empty);
15692 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15694 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15695 if (r.lastWakeTime != 0) {
15697 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15698 synchronized (stats) {
15699 wtime = stats.getProcessWakeTime(r.info.uid,
15700 r.pid, curRealtime);
15702 long timeUsed = wtime - r.lastWakeTime;
15705 pw.print("keep awake over ");
15706 TimeUtils.formatDuration(realtimeSince, pw);
15707 pw.print(" used ");
15708 TimeUtils.formatDuration(timeUsed, pw);
15710 pw.print((timeUsed*100)/realtimeSince);
15713 if (r.lastCpuTime != 0) {
15714 long timeUsed = r.curCpuTime - r.lastCpuTime;
15717 pw.print("run cpu over ");
15718 TimeUtils.formatDuration(uptimeSince, pw);
15719 pw.print(" used ");
15720 TimeUtils.formatDuration(timeUsed, pw);
15722 pw.print((timeUsed*100)/uptimeSince);
15731 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15733 ArrayList<ProcessRecord> procs;
15734 synchronized (this) {
15735 if (args != null && args.length > start
15736 && args[start].charAt(0) != '-') {
15737 procs = new ArrayList<ProcessRecord>();
15740 pid = Integer.parseInt(args[start]);
15741 } catch (NumberFormatException e) {
15743 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15744 ProcessRecord proc = mLruProcesses.get(i);
15745 if (proc.pid == pid) {
15747 } else if (allPkgs && proc.pkgList != null
15748 && proc.pkgList.containsKey(args[start])) {
15750 } else if (proc.processName.equals(args[start])) {
15754 if (procs.size() <= 0) {
15758 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15764 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15765 PrintWriter pw, String[] args) {
15766 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15767 if (procs == null) {
15768 pw.println("No process found for: " + args[0]);
15772 long uptime = SystemClock.uptimeMillis();
15773 long realtime = SystemClock.elapsedRealtime();
15774 pw.println("Applications Graphics Acceleration Info:");
15775 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15777 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15778 ProcessRecord r = procs.get(i);
15779 if (r.thread != null) {
15780 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15783 TransferPipe tp = new TransferPipe();
15785 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15790 } catch (IOException e) {
15791 pw.println("Failure while dumping the app: " + r);
15793 } catch (RemoteException e) {
15794 pw.println("Got a RemoteException while dumping the app " + r);
15801 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15802 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15803 if (procs == null) {
15804 pw.println("No process found for: " + args[0]);
15808 pw.println("Applications Database Info:");
15810 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15811 ProcessRecord r = procs.get(i);
15812 if (r.thread != null) {
15813 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15816 TransferPipe tp = new TransferPipe();
15818 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15823 } catch (IOException e) {
15824 pw.println("Failure while dumping the app: " + r);
15826 } catch (RemoteException e) {
15827 pw.println("Got a RemoteException while dumping the app " + r);
15834 final static class MemItem {
15835 final boolean isProc;
15836 final String label;
15837 final String shortLabel;
15839 final long swapPss;
15841 final boolean hasActivities;
15842 ArrayList<MemItem> subitems;
15844 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15845 boolean _hasActivities) {
15848 shortLabel = _shortLabel;
15850 swapPss = _swapPss;
15852 hasActivities = _hasActivities;
15855 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15858 shortLabel = _shortLabel;
15860 swapPss = _swapPss;
15862 hasActivities = false;
15866 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15867 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15868 if (sort && !isCompact) {
15869 Collections.sort(items, new Comparator<MemItem>() {
15871 public int compare(MemItem lhs, MemItem rhs) {
15872 if (lhs.pss < rhs.pss) {
15874 } else if (lhs.pss > rhs.pss) {
15882 for (int i=0; i<items.size(); i++) {
15883 MemItem mi = items.get(i);
15886 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15887 mi.label, stringifyKBSize(mi.swapPss));
15889 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15891 } else if (mi.isProc) {
15892 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15893 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15894 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15895 pw.println(mi.hasActivities ? ",a" : ",e");
15897 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15898 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15900 if (mi.subitems != null) {
15901 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15902 true, isCompact, dumpSwapPss);
15907 // These are in KB.
15908 static final long[] DUMP_MEM_BUCKETS = new long[] {
15909 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15910 120*1024, 160*1024, 200*1024,
15911 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15912 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15915 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15916 boolean stackLike) {
15917 int start = label.lastIndexOf('.');
15918 if (start >= 0) start++;
15920 int end = label.length();
15921 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15922 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15923 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15924 out.append(bucket);
15925 out.append(stackLike ? "MB." : "MB ");
15926 out.append(label, start, end);
15930 out.append(memKB/1024);
15931 out.append(stackLike ? "MB." : "MB ");
15932 out.append(label, start, end);
15935 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15936 ProcessList.NATIVE_ADJ,
15937 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15938 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15939 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15940 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15941 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15942 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15944 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15946 "System", "Persistent", "Persistent Service", "Foreground",
15947 "Visible", "Perceptible",
15948 "Heavy Weight", "Backup",
15949 "A Services", "Home",
15950 "Previous", "B Services", "Cached"
15952 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15954 "sys", "pers", "persvc", "fore",
15957 "servicea", "home",
15958 "prev", "serviceb", "cached"
15961 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15962 long realtime, boolean isCheckinRequest, boolean isCompact) {
15964 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15966 if (isCheckinRequest || isCompact) {
15967 // short checkin version
15968 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15970 pw.println("Applications Memory Usage (in Kilobytes):");
15971 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15975 private static final int KSM_SHARED = 0;
15976 private static final int KSM_SHARING = 1;
15977 private static final int KSM_UNSHARED = 2;
15978 private static final int KSM_VOLATILE = 3;
15980 private final long[] getKsmInfo() {
15981 long[] longOut = new long[4];
15982 final int[] SINGLE_LONG_FORMAT = new int[] {
15983 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15985 long[] longTmp = new long[1];
15986 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15987 SINGLE_LONG_FORMAT, null, longTmp, null);
15988 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15990 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15991 SINGLE_LONG_FORMAT, null, longTmp, null);
15992 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15994 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15995 SINGLE_LONG_FORMAT, null, longTmp, null);
15996 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15998 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15999 SINGLE_LONG_FORMAT, null, longTmp, null);
16000 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16004 private static String stringifySize(long size, int order) {
16005 Locale locale = Locale.US;
16008 return String.format(locale, "%,13d", size);
16010 return String.format(locale, "%,9dK", size / 1024);
16012 return String.format(locale, "%,5dM", size / 1024 / 1024);
16013 case 1024 * 1024 * 1024:
16014 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16016 throw new IllegalArgumentException("Invalid size order");
16020 private static String stringifyKBSize(long size) {
16021 return stringifySize(size * 1024, 1024);
16024 // Update this version number in case you change the 'compact' format
16025 private static final int MEMINFO_COMPACT_VERSION = 1;
16027 final void dumpApplicationMemoryUsage(FileDescriptor fd,
16028 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16029 boolean dumpDetails = false;
16030 boolean dumpFullDetails = false;
16031 boolean dumpDalvik = false;
16032 boolean dumpSummaryOnly = false;
16033 boolean dumpUnreachable = false;
16034 boolean oomOnly = false;
16035 boolean isCompact = false;
16036 boolean localOnly = false;
16037 boolean packages = false;
16038 boolean isCheckinRequest = false;
16039 boolean dumpSwapPss = false;
16042 while (opti < args.length) {
16043 String opt = args[opti];
16044 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16048 if ("-a".equals(opt)) {
16049 dumpDetails = true;
16050 dumpFullDetails = true;
16052 dumpSwapPss = true;
16053 } else if ("-d".equals(opt)) {
16055 } else if ("-c".equals(opt)) {
16057 } else if ("-s".equals(opt)) {
16058 dumpDetails = true;
16059 dumpSummaryOnly = true;
16060 } else if ("-S".equals(opt)) {
16061 dumpSwapPss = true;
16062 } else if ("--unreachable".equals(opt)) {
16063 dumpUnreachable = true;
16064 } else if ("--oom".equals(opt)) {
16066 } else if ("--local".equals(opt)) {
16068 } else if ("--package".equals(opt)) {
16070 } else if ("--checkin".equals(opt)) {
16071 isCheckinRequest = true;
16073 } else if ("-h".equals(opt)) {
16074 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16075 pw.println(" -a: include all available information for each process.");
16076 pw.println(" -d: include dalvik details.");
16077 pw.println(" -c: dump in a compact machine-parseable representation.");
16078 pw.println(" -s: dump only summary of application memory usage.");
16079 pw.println(" -S: dump also SwapPss.");
16080 pw.println(" --oom: only show processes organized by oom adj.");
16081 pw.println(" --local: only collect details locally, don't call process.");
16082 pw.println(" --package: interpret process arg as package, dumping all");
16083 pw.println(" processes that have loaded that package.");
16084 pw.println(" --checkin: dump data for a checkin");
16085 pw.println("If [process] is specified it can be the name or ");
16086 pw.println("pid of a specific process to dump.");
16089 pw.println("Unknown argument: " + opt + "; use -h for help");
16093 long uptime = SystemClock.uptimeMillis();
16094 long realtime = SystemClock.elapsedRealtime();
16095 final long[] tmpLong = new long[1];
16097 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16098 if (procs == null) {
16099 // No Java processes. Maybe they want to print a native process.
16100 if (args != null && args.length > opti
16101 && args[opti].charAt(0) != '-') {
16102 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16103 = new ArrayList<ProcessCpuTracker.Stats>();
16104 updateCpuStatsNow();
16107 findPid = Integer.parseInt(args[opti]);
16108 } catch (NumberFormatException e) {
16110 synchronized (mProcessCpuTracker) {
16111 final int N = mProcessCpuTracker.countStats();
16112 for (int i=0; i<N; i++) {
16113 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16114 if (st.pid == findPid || (st.baseName != null
16115 && st.baseName.equals(args[opti]))) {
16116 nativeProcs.add(st);
16120 if (nativeProcs.size() > 0) {
16121 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16123 Debug.MemoryInfo mi = null;
16124 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16125 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16126 final int pid = r.pid;
16127 if (!isCheckinRequest && dumpDetails) {
16128 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16131 mi = new Debug.MemoryInfo();
16133 if (dumpDetails || (!brief && !oomOnly)) {
16134 Debug.getMemoryInfo(pid, mi);
16136 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16137 mi.dalvikPrivateDirty = (int)tmpLong[0];
16139 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16140 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16141 if (isCheckinRequest) {
16148 pw.println("No process found for: " + args[opti]);
16152 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16153 dumpDetails = true;
16156 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16158 String[] innerArgs = new String[args.length-opti];
16159 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16161 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16162 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16163 long nativePss = 0;
16164 long nativeSwapPss = 0;
16165 long dalvikPss = 0;
16166 long dalvikSwapPss = 0;
16167 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16169 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16172 long otherSwapPss = 0;
16173 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16174 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16176 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16177 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16178 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16179 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16182 long totalSwapPss = 0;
16183 long cachedPss = 0;
16184 long cachedSwapPss = 0;
16185 boolean hasSwapPss = false;
16187 Debug.MemoryInfo mi = null;
16188 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16189 final ProcessRecord r = procs.get(i);
16190 final IApplicationThread thread;
16193 final boolean hasActivities;
16194 synchronized (this) {
16197 oomAdj = r.getSetAdjWithServices();
16198 hasActivities = r.activities.size() > 0;
16200 if (thread != null) {
16201 if (!isCheckinRequest && dumpDetails) {
16202 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16205 mi = new Debug.MemoryInfo();
16207 if (dumpDetails || (!brief && !oomOnly)) {
16208 Debug.getMemoryInfo(pid, mi);
16209 hasSwapPss = mi.hasSwappedOutPss;
16211 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16212 mi.dalvikPrivateDirty = (int)tmpLong[0];
16216 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16217 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16218 if (isCheckinRequest) {
16224 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16225 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16226 } catch (RemoteException e) {
16227 if (!isCheckinRequest) {
16228 pw.println("Got RemoteException!");
16235 final long myTotalPss = mi.getTotalPss();
16236 final long myTotalUss = mi.getTotalUss();
16237 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16239 synchronized (this) {
16240 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16241 // Record this for posterity if the process has been stable.
16242 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16246 if (!isCheckinRequest && mi != null) {
16247 totalPss += myTotalPss;
16248 totalSwapPss += myTotalSwapPss;
16249 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16250 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16251 myTotalSwapPss, pid, hasActivities);
16252 procMems.add(pssItem);
16253 procMemsMap.put(pid, pssItem);
16255 nativePss += mi.nativePss;
16256 nativeSwapPss += mi.nativeSwappedOutPss;
16257 dalvikPss += mi.dalvikPss;
16258 dalvikSwapPss += mi.dalvikSwappedOutPss;
16259 for (int j=0; j<dalvikSubitemPss.length; j++) {
16260 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16261 dalvikSubitemSwapPss[j] +=
16262 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16264 otherPss += mi.otherPss;
16265 otherSwapPss += mi.otherSwappedOutPss;
16266 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16267 long mem = mi.getOtherPss(j);
16270 mem = mi.getOtherSwappedOutPss(j);
16271 miscSwapPss[j] += mem;
16272 otherSwapPss -= mem;
16275 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16276 cachedPss += myTotalPss;
16277 cachedSwapPss += myTotalSwapPss;
16280 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16281 if (oomIndex == (oomPss.length - 1)
16282 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16283 && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16284 oomPss[oomIndex] += myTotalPss;
16285 oomSwapPss[oomIndex] += myTotalSwapPss;
16286 if (oomProcs[oomIndex] == null) {
16287 oomProcs[oomIndex] = new ArrayList<MemItem>();
16289 oomProcs[oomIndex].add(pssItem);
16297 long nativeProcTotalPss = 0;
16299 if (!isCheckinRequest && procs.size() > 1 && !packages) {
16300 // If we are showing aggregations, also look for native processes to
16301 // include so that our aggregations are more accurate.
16302 updateCpuStatsNow();
16304 synchronized (mProcessCpuTracker) {
16305 final int N = mProcessCpuTracker.countStats();
16306 for (int i=0; i<N; i++) {
16307 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16308 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16310 mi = new Debug.MemoryInfo();
16312 if (!brief && !oomOnly) {
16313 Debug.getMemoryInfo(st.pid, mi);
16315 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16316 mi.nativePrivateDirty = (int)tmpLong[0];
16319 final long myTotalPss = mi.getTotalPss();
16320 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16321 totalPss += myTotalPss;
16322 nativeProcTotalPss += myTotalPss;
16324 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16325 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16326 procMems.add(pssItem);
16328 nativePss += mi.nativePss;
16329 nativeSwapPss += mi.nativeSwappedOutPss;
16330 dalvikPss += mi.dalvikPss;
16331 dalvikSwapPss += mi.dalvikSwappedOutPss;
16332 for (int j=0; j<dalvikSubitemPss.length; j++) {
16333 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16334 dalvikSubitemSwapPss[j] +=
16335 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16337 otherPss += mi.otherPss;
16338 otherSwapPss += mi.otherSwappedOutPss;
16339 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16340 long mem = mi.getOtherPss(j);
16343 mem = mi.getOtherSwappedOutPss(j);
16344 miscSwapPss[j] += mem;
16345 otherSwapPss -= mem;
16347 oomPss[0] += myTotalPss;
16348 oomSwapPss[0] += myTotalSwapPss;
16349 if (oomProcs[0] == null) {
16350 oomProcs[0] = new ArrayList<MemItem>();
16352 oomProcs[0].add(pssItem);
16357 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16359 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16360 final MemItem dalvikItem =
16361 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16362 if (dalvikSubitemPss.length > 0) {
16363 dalvikItem.subitems = new ArrayList<MemItem>();
16364 for (int j=0; j<dalvikSubitemPss.length; j++) {
16365 final String name = Debug.MemoryInfo.getOtherLabel(
16366 Debug.MemoryInfo.NUM_OTHER_STATS + j);
16367 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16368 dalvikSubitemSwapPss[j], j));
16371 catMems.add(dalvikItem);
16372 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16373 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16374 String label = Debug.MemoryInfo.getOtherLabel(j);
16375 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16378 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16379 for (int j=0; j<oomPss.length; j++) {
16380 if (oomPss[j] != 0) {
16381 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16382 : DUMP_MEM_OOM_LABEL[j];
16383 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16384 DUMP_MEM_OOM_ADJ[j]);
16385 item.subitems = oomProcs[j];
16390 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16391 if (!brief && !oomOnly && !isCompact) {
16393 pw.println("Total PSS by process:");
16394 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
16398 pw.println("Total PSS by OOM adjustment:");
16400 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
16401 if (!brief && !oomOnly) {
16402 PrintWriter out = categoryPw != null ? categoryPw : pw;
16405 out.println("Total PSS by category:");
16407 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
16412 MemInfoReader memInfo = new MemInfoReader();
16413 memInfo.readMemInfo();
16414 if (nativeProcTotalPss > 0) {
16415 synchronized (this) {
16416 final long cachedKb = memInfo.getCachedSizeKb();
16417 final long freeKb = memInfo.getFreeSizeKb();
16418 final long zramKb = memInfo.getZramTotalSizeKb();
16419 final long kernelKb = memInfo.getKernelUsedSizeKb();
16420 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16421 kernelKb*1024, nativeProcTotalPss*1024);
16422 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16423 nativeProcTotalPss);
16428 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16429 pw.print(" (status ");
16430 switch (mLastMemoryLevel) {
16431 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16432 pw.println("normal)");
16434 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16435 pw.println("moderate)");
16437 case ProcessStats.ADJ_MEM_FACTOR_LOW:
16438 pw.println("low)");
16440 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16441 pw.println("critical)");
16444 pw.print(mLastMemoryLevel);
16448 pw.print(" Free RAM: ");
16449 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16450 + memInfo.getFreeSizeKb()));
16452 pw.print(stringifyKBSize(cachedPss));
16453 pw.print(" cached pss + ");
16454 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16455 pw.print(" cached kernel + ");
16456 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16457 pw.println(" free)");
16459 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16460 pw.print(cachedPss + memInfo.getCachedSizeKb()
16461 + memInfo.getFreeSizeKb()); pw.print(",");
16462 pw.println(totalPss - cachedPss);
16465 long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16466 - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16467 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16469 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16470 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16471 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16472 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16473 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16475 pw.print("lostram,"); pw.println(lostRAM);
16478 if (memInfo.getZramTotalSizeKb() != 0) {
16480 pw.print(" ZRAM: ");
16481 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16482 pw.print(" physical used for ");
16483 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16484 - memInfo.getSwapFreeSizeKb()));
16485 pw.print(" in swap (");
16486 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16487 pw.println(" total swap)");
16489 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16490 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16491 pw.println(memInfo.getSwapFreeSizeKb());
16494 final long[] ksm = getKsmInfo();
16496 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16497 || ksm[KSM_VOLATILE] != 0) {
16498 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16499 pw.print(" saved from shared ");
16500 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16501 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16502 pw.print(" unshared; ");
16503 pw.print(stringifyKBSize(
16504 ksm[KSM_VOLATILE])); pw.println(" volatile");
16506 pw.print(" Tuning: ");
16507 pw.print(ActivityManager.staticGetMemoryClass());
16508 pw.print(" (large ");
16509 pw.print(ActivityManager.staticGetLargeMemoryClass());
16510 pw.print("), oom ");
16511 pw.print(stringifySize(
16512 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16513 pw.print(", restore limit ");
16514 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16515 if (ActivityManager.isLowRamDeviceStatic()) {
16516 pw.print(" (low-ram)");
16518 if (ActivityManager.isHighEndGfx()) {
16519 pw.print(" (high-end-gfx)");
16523 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16524 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16525 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16526 pw.print("tuning,");
16527 pw.print(ActivityManager.staticGetMemoryClass());
16529 pw.print(ActivityManager.staticGetLargeMemoryClass());
16531 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16532 if (ActivityManager.isLowRamDeviceStatic()) {
16533 pw.print(",low-ram");
16535 if (ActivityManager.isHighEndGfx()) {
16536 pw.print(",high-end-gfx");
16544 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16545 long memtrack, String name) {
16547 sb.append(ProcessList.makeOomAdjString(oomAdj));
16549 sb.append(ProcessList.makeProcStateString(procState));
16551 ProcessList.appendRamKb(sb, pss);
16554 if (memtrack > 0) {
16556 sb.append(stringifyKBSize(memtrack));
16557 sb.append(" memtrack)");
16561 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16562 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16563 sb.append(" (pid ");
16566 sb.append(mi.adjType);
16568 if (mi.adjReason != null) {
16570 sb.append(mi.adjReason);
16575 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16576 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16577 for (int i=0, N=memInfos.size(); i<N; i++) {
16578 ProcessMemInfo mi = memInfos.get(i);
16579 infoMap.put(mi.pid, mi);
16581 updateCpuStatsNow();
16582 long[] memtrackTmp = new long[1];
16583 synchronized (mProcessCpuTracker) {
16584 final int N = mProcessCpuTracker.countStats();
16585 for (int i=0; i<N; i++) {
16586 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16587 if (st.vsize > 0) {
16588 long pss = Debug.getPss(st.pid, null, memtrackTmp);
16590 if (infoMap.indexOfKey(st.pid) < 0) {
16591 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16592 ProcessList.NATIVE_ADJ, -1, "native", null);
16594 mi.memtrack = memtrackTmp[0];
16603 long totalMemtrack = 0;
16604 for (int i=0, N=memInfos.size(); i<N; i++) {
16605 ProcessMemInfo mi = memInfos.get(i);
16607 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16608 mi.memtrack = memtrackTmp[0];
16610 totalPss += mi.pss;
16611 totalMemtrack += mi.memtrack;
16613 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16614 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16615 if (lhs.oomAdj != rhs.oomAdj) {
16616 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16618 if (lhs.pss != rhs.pss) {
16619 return lhs.pss < rhs.pss ? 1 : -1;
16625 StringBuilder tag = new StringBuilder(128);
16626 StringBuilder stack = new StringBuilder(128);
16627 tag.append("Low on memory -- ");
16628 appendMemBucket(tag, totalPss, "total", false);
16629 appendMemBucket(stack, totalPss, "total", true);
16631 StringBuilder fullNativeBuilder = new StringBuilder(1024);
16632 StringBuilder shortNativeBuilder = new StringBuilder(1024);
16633 StringBuilder fullJavaBuilder = new StringBuilder(1024);
16635 boolean firstLine = true;
16636 int lastOomAdj = Integer.MIN_VALUE;
16637 long extraNativeRam = 0;
16638 long extraNativeMemtrack = 0;
16639 long cachedPss = 0;
16640 for (int i=0, N=memInfos.size(); i<N; i++) {
16641 ProcessMemInfo mi = memInfos.get(i);
16643 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16644 cachedPss += mi.pss;
16647 if (mi.oomAdj != ProcessList.NATIVE_ADJ
16648 && (mi.oomAdj < ProcessList.SERVICE_ADJ
16649 || mi.oomAdj == ProcessList.HOME_APP_ADJ
16650 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16651 if (lastOomAdj != mi.oomAdj) {
16652 lastOomAdj = mi.oomAdj;
16653 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16656 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16661 stack.append("\n\t at ");
16669 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16670 appendMemBucket(tag, mi.pss, mi.name, false);
16672 appendMemBucket(stack, mi.pss, mi.name, true);
16673 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16674 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16676 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16677 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16678 stack.append(DUMP_MEM_OOM_LABEL[k]);
16680 stack.append(DUMP_MEM_OOM_ADJ[k]);
16687 appendMemInfo(fullNativeBuilder, mi);
16688 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16689 // The short form only has native processes that are >= 512K.
16690 if (mi.pss >= 512) {
16691 appendMemInfo(shortNativeBuilder, mi);
16693 extraNativeRam += mi.pss;
16694 extraNativeMemtrack += mi.memtrack;
16697 // Short form has all other details, but if we have collected RAM
16698 // from smaller native processes let's dump a summary of that.
16699 if (extraNativeRam > 0) {
16700 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16701 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16702 shortNativeBuilder.append('\n');
16703 extraNativeRam = 0;
16705 appendMemInfo(fullJavaBuilder, mi);
16709 fullJavaBuilder.append(" ");
16710 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16711 fullJavaBuilder.append(": TOTAL");
16712 if (totalMemtrack > 0) {
16713 fullJavaBuilder.append(" (");
16714 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16715 fullJavaBuilder.append(" memtrack)");
16718 fullJavaBuilder.append("\n");
16720 MemInfoReader memInfo = new MemInfoReader();
16721 memInfo.readMemInfo();
16722 final long[] infos = memInfo.getRawInfo();
16724 StringBuilder memInfoBuilder = new StringBuilder(1024);
16725 Debug.getMemInfo(infos);
16726 memInfoBuilder.append(" MemInfo: ");
16727 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16728 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16729 memInfoBuilder.append(stringifyKBSize(
16730 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16731 memInfoBuilder.append(stringifyKBSize(
16732 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16733 memInfoBuilder.append(stringifyKBSize(
16734 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16735 memInfoBuilder.append(" ");
16736 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16737 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16738 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16739 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16740 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16741 memInfoBuilder.append(" ZRAM: ");
16742 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16743 memInfoBuilder.append(" RAM, ");
16744 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16745 memInfoBuilder.append(" swap total, ");
16746 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16747 memInfoBuilder.append(" swap free\n");
16749 final long[] ksm = getKsmInfo();
16750 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16751 || ksm[KSM_VOLATILE] != 0) {
16752 memInfoBuilder.append(" KSM: ");
16753 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16754 memInfoBuilder.append(" saved from shared ");
16755 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16756 memInfoBuilder.append("\n ");
16757 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16758 memInfoBuilder.append(" unshared; ");
16759 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16760 memInfoBuilder.append(" volatile\n");
16762 memInfoBuilder.append(" Free RAM: ");
16763 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16764 + memInfo.getFreeSizeKb()));
16765 memInfoBuilder.append("\n");
16766 memInfoBuilder.append(" Used RAM: ");
16767 memInfoBuilder.append(stringifyKBSize(
16768 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16769 memInfoBuilder.append("\n");
16770 memInfoBuilder.append(" Lost RAM: ");
16771 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16772 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16773 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16774 memInfoBuilder.append("\n");
16775 Slog.i(TAG, "Low on memory:");
16776 Slog.i(TAG, shortNativeBuilder.toString());
16777 Slog.i(TAG, fullJavaBuilder.toString());
16778 Slog.i(TAG, memInfoBuilder.toString());
16780 StringBuilder dropBuilder = new StringBuilder(1024);
16782 StringWriter oomSw = new StringWriter();
16783 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16784 StringWriter catSw = new StringWriter();
16785 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16786 String[] emptyArgs = new String[] { };
16787 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16789 String oomString = oomSw.toString();
16791 dropBuilder.append("Low on memory:");
16792 dropBuilder.append(stack);
16793 dropBuilder.append('\n');
16794 dropBuilder.append(fullNativeBuilder);
16795 dropBuilder.append(fullJavaBuilder);
16796 dropBuilder.append('\n');
16797 dropBuilder.append(memInfoBuilder);
16798 dropBuilder.append('\n');
16800 dropBuilder.append(oomString);
16801 dropBuilder.append('\n');
16803 StringWriter catSw = new StringWriter();
16804 synchronized (ActivityManagerService.this) {
16805 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16806 String[] emptyArgs = new String[] { };
16808 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16810 mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16811 false, null).dumpLocked();
16813 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16816 dropBuilder.append(catSw.toString());
16817 addErrorToDropBox("lowmem", null, "system_server", null,
16818 null, tag.toString(), dropBuilder.toString(), null, null);
16819 //Slog.i(TAG, "Sent to dropbox:");
16820 //Slog.i(TAG, dropBuilder.toString());
16821 synchronized (ActivityManagerService.this) {
16822 long now = SystemClock.uptimeMillis();
16823 if (mLastMemUsageReportTime < now) {
16824 mLastMemUsageReportTime = now;
16830 * Searches array of arguments for the specified string
16831 * @param args array of argument strings
16832 * @param value value to search for
16833 * @return true if the value is contained in the array
16835 private static boolean scanArgs(String[] args, String value) {
16836 if (args != null) {
16837 for (String arg : args) {
16838 if (value.equals(arg)) {
16846 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16847 ContentProviderRecord cpr, boolean always) {
16848 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16850 if (!inLaunching || always) {
16851 synchronized (cpr) {
16852 cpr.launchingApp = null;
16855 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16856 String names[] = cpr.info.authority.split(";");
16857 for (int j = 0; j < names.length; j++) {
16858 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16862 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16863 ContentProviderConnection conn = cpr.connections.get(i);
16864 if (conn.waiting) {
16865 // If this connection is waiting for the provider, then we don't
16866 // need to mess with its process unless we are always removing
16867 // or for some reason the provider is not currently launching.
16868 if (inLaunching && !always) {
16872 ProcessRecord capp = conn.client;
16874 if (conn.stableCount > 0) {
16875 if (!capp.persistent && capp.thread != null
16877 && capp.pid != MY_PID) {
16878 capp.kill("depends on provider "
16879 + cpr.name.flattenToShortString()
16880 + " in dying proc " + (proc != null ? proc.processName : "??")
16881 + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16883 } else if (capp.thread != null && conn.provider.provider != null) {
16885 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16886 } catch (RemoteException e) {
16888 // In the protocol here, we don't expect the client to correctly
16889 // clean up this connection, we'll just remove it.
16890 cpr.connections.remove(i);
16891 if (conn.client.conProviders.remove(conn)) {
16892 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16897 if (inLaunching && always) {
16898 mLaunchingProviders.remove(cpr);
16900 return inLaunching;
16904 * Main code for cleaning up a process when it has gone away. This is
16905 * called both as a result of the process dying, or directly when stopping
16906 * a process when running in single process mode.
16908 * @return Returns true if the given process has been restarted, so the
16909 * app that was passed in must remain on the process lists.
16911 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16912 boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16913 Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16915 removeLruProcessLocked(app);
16916 ProcessList.remove(app.pid);
16919 mProcessesToGc.remove(app);
16920 mPendingPssProcesses.remove(app);
16922 // Dismiss any open dialogs.
16923 if (app.crashDialog != null && !app.forceCrashReport) {
16924 app.crashDialog.dismiss();
16925 app.crashDialog = null;
16927 if (app.anrDialog != null) {
16928 app.anrDialog.dismiss();
16929 app.anrDialog = null;
16931 if (app.waitDialog != null) {
16932 app.waitDialog.dismiss();
16933 app.waitDialog = null;
16936 app.crashing = false;
16937 app.notResponding = false;
16939 app.resetPackageList(mProcessStats);
16940 app.unlinkDeathRecipient();
16941 app.makeInactive(mProcessStats);
16942 app.waitingToKill = null;
16943 app.forcingToForeground = null;
16944 updateProcessForegroundLocked(app, false, false);
16945 app.foregroundActivities = false;
16946 app.hasShownUi = false;
16947 app.treatLikeActivity = false;
16948 app.hasAboveClient = false;
16949 app.hasClientActivities = false;
16951 mServices.killServicesLocked(app, allowRestart);
16953 boolean restart = false;
16955 // Remove published content providers.
16956 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16957 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16958 final boolean always = app.bad || !allowRestart;
16959 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16960 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16961 // We left the provider in the launching list, need to
16966 cpr.provider = null;
16969 app.pubProviders.clear();
16971 // Take care of any launching providers waiting for this process.
16972 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16976 // Unregister from connected content providers.
16977 if (!app.conProviders.isEmpty()) {
16978 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16979 ContentProviderConnection conn = app.conProviders.get(i);
16980 conn.provider.connections.remove(conn);
16981 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16982 conn.provider.name);
16984 app.conProviders.clear();
16987 // At this point there may be remaining entries in mLaunchingProviders
16988 // where we were the only one waiting, so they are no longer of use.
16989 // Look for these and clean up if found.
16990 // XXX Commented out for now. Trying to figure out a way to reproduce
16991 // the actual situation to identify what is actually going on.
16993 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16994 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16995 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16996 synchronized (cpr) {
16997 cpr.launchingApp = null;
17004 skipCurrentReceiverLocked(app);
17006 // Unregister any receivers.
17007 for (int i = app.receivers.size() - 1; i >= 0; i--) {
17008 removeReceiverLocked(app.receivers.valueAt(i));
17010 app.receivers.clear();
17012 // If the app is undergoing backup, tell the backup manager about it
17013 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17014 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17015 + mBackupTarget.appInfo + " died during backup");
17017 IBackupManager bm = IBackupManager.Stub.asInterface(
17018 ServiceManager.getService(Context.BACKUP_SERVICE));
17019 bm.agentDisconnected(app.info.packageName);
17020 } catch (RemoteException e) {
17021 // can't happen; backup manager is local
17025 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17026 ProcessChangeItem item = mPendingProcessChanges.get(i);
17027 if (item.pid == app.pid) {
17028 mPendingProcessChanges.remove(i);
17029 mAvailProcessChanges.add(item);
17032 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17033 null).sendToTarget();
17035 // If the caller is restarting this app, then leave it in its
17036 // current lists and let the caller take care of it.
17041 if (!app.persistent || app.isolated) {
17042 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17043 "Removing non-persistent process during cleanup: " + app);
17044 if (!replacingPid) {
17045 removeProcessNameLocked(app.processName, app.uid);
17047 if (mHeavyWeightProcess == app) {
17048 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17049 mHeavyWeightProcess.userId, 0));
17050 mHeavyWeightProcess = null;
17052 } else if (!app.removed) {
17053 // This app is persistent, so we need to keep its record around.
17054 // If it is not already on the pending app list, add it there
17055 // and start a new process for it.
17056 if (mPersistentStartingProcesses.indexOf(app) < 0) {
17057 mPersistentStartingProcesses.add(app);
17061 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17062 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17063 mProcessesOnHold.remove(app);
17065 if (app == mHomeProcess) {
17066 mHomeProcess = null;
17068 if (app == mPreviousProcess) {
17069 mPreviousProcess = null;
17072 if (restart && !app.isolated) {
17073 // We have components that still need to be running in the
17074 // process, so re-launch it.
17076 ProcessList.remove(app.pid);
17078 addProcessNameLocked(app);
17079 startProcessLocked(app, "restart", app.processName);
17081 } else if (app.pid > 0 && app.pid != MY_PID) {
17084 synchronized (mPidsSelfLocked) {
17085 mPidsSelfLocked.remove(app.pid);
17086 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17088 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17089 if (app.isolated) {
17090 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17097 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17098 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17099 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17100 if (cpr.launchingApp == app) {
17107 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17108 // Look through the content providers we are waiting to have launched,
17109 // and if any run in this process then either schedule a restart of
17110 // the process or kill the client waiting for it if this process has
17112 boolean restart = false;
17113 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17114 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17115 if (cpr.launchingApp == app) {
17116 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17119 removeDyingProviderLocked(app, cpr, true);
17126 // =========================================================
17128 // =========================================================
17131 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17133 enforceNotIsolatedCaller("getServices");
17134 synchronized (this) {
17135 return mServices.getRunningServiceInfoLocked(maxNum, flags);
17140 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17141 enforceNotIsolatedCaller("getRunningServiceControlPanel");
17142 synchronized (this) {
17143 return mServices.getRunningServiceControlPanelLocked(name);
17148 public ComponentName startService(IApplicationThread caller, Intent service,
17149 String resolvedType, String callingPackage, int userId)
17150 throws TransactionTooLargeException {
17151 enforceNotIsolatedCaller("startService");
17152 // Refuse possible leaked file descriptors
17153 if (service != null && service.hasFileDescriptors() == true) {
17154 throw new IllegalArgumentException("File descriptors passed in Intent");
17157 if (callingPackage == null) {
17158 throw new IllegalArgumentException("callingPackage cannot be null");
17161 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17162 "startService: " + service + " type=" + resolvedType);
17163 synchronized(this) {
17164 final int callingPid = Binder.getCallingPid();
17165 final int callingUid = Binder.getCallingUid();
17166 final long origId = Binder.clearCallingIdentity();
17167 ComponentName res = mServices.startServiceLocked(caller, service,
17168 resolvedType, callingPid, callingUid, callingPackage, userId);
17169 Binder.restoreCallingIdentity(origId);
17174 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17175 String callingPackage, int userId)
17176 throws TransactionTooLargeException {
17177 synchronized(this) {
17178 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17179 "startServiceInPackage: " + service + " type=" + resolvedType);
17180 final long origId = Binder.clearCallingIdentity();
17181 ComponentName res = mServices.startServiceLocked(null, service,
17182 resolvedType, -1, uid, callingPackage, userId);
17183 Binder.restoreCallingIdentity(origId);
17189 public int stopService(IApplicationThread caller, Intent service,
17190 String resolvedType, int userId) {
17191 enforceNotIsolatedCaller("stopService");
17192 // Refuse possible leaked file descriptors
17193 if (service != null && service.hasFileDescriptors() == true) {
17194 throw new IllegalArgumentException("File descriptors passed in Intent");
17197 synchronized(this) {
17198 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17203 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17204 enforceNotIsolatedCaller("peekService");
17205 // Refuse possible leaked file descriptors
17206 if (service != null && service.hasFileDescriptors() == true) {
17207 throw new IllegalArgumentException("File descriptors passed in Intent");
17210 if (callingPackage == null) {
17211 throw new IllegalArgumentException("callingPackage cannot be null");
17214 synchronized(this) {
17215 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17220 public boolean stopServiceToken(ComponentName className, IBinder token,
17222 synchronized(this) {
17223 return mServices.stopServiceTokenLocked(className, token, startId);
17228 public void setServiceForeground(ComponentName className, IBinder token,
17229 int id, Notification notification, int flags) {
17230 synchronized(this) {
17231 mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17236 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17237 boolean requireFull, String name, String callerPackage) {
17238 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17239 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17242 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17243 String className, int flags) {
17244 boolean result = false;
17245 // For apps that don't have pre-defined UIDs, check for permission
17246 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17247 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17248 if (ActivityManager.checkUidPermission(
17249 INTERACT_ACROSS_USERS,
17250 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17251 ComponentName comp = new ComponentName(aInfo.packageName, className);
17252 String msg = "Permission Denial: Component " + comp.flattenToShortString()
17253 + " requests FLAG_SINGLE_USER, but app does not hold "
17254 + INTERACT_ACROSS_USERS;
17256 throw new SecurityException(msg);
17258 // Permission passed
17261 } else if ("system".equals(componentProcessName)) {
17263 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17264 // Phone app and persistent apps are allowed to export singleuser providers.
17265 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17266 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17268 if (DEBUG_MU) Slog.v(TAG_MU,
17269 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17270 + Integer.toHexString(flags) + ") = " + result);
17275 * Checks to see if the caller is in the same app as the singleton
17276 * component, or the component is in a special app. It allows special apps
17277 * to export singleton components but prevents exporting singleton
17278 * components for regular apps.
17280 boolean isValidSingletonCall(int callingUid, int componentUid) {
17281 int componentAppId = UserHandle.getAppId(componentUid);
17282 return UserHandle.isSameApp(callingUid, componentUid)
17283 || componentAppId == Process.SYSTEM_UID
17284 || componentAppId == Process.PHONE_UID
17285 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17286 == PackageManager.PERMISSION_GRANTED;
17289 public int bindService(IApplicationThread caller, IBinder token, Intent service,
17290 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17291 int userId) throws TransactionTooLargeException {
17292 enforceNotIsolatedCaller("bindService");
17294 // Refuse possible leaked file descriptors
17295 if (service != null && service.hasFileDescriptors() == true) {
17296 throw new IllegalArgumentException("File descriptors passed in Intent");
17299 if (callingPackage == null) {
17300 throw new IllegalArgumentException("callingPackage cannot be null");
17303 synchronized(this) {
17304 return mServices.bindServiceLocked(caller, token, service,
17305 resolvedType, connection, flags, callingPackage, userId);
17309 public boolean unbindService(IServiceConnection connection) {
17310 synchronized (this) {
17311 return mServices.unbindServiceLocked(connection);
17315 public void publishService(IBinder token, Intent intent, IBinder service) {
17316 // Refuse possible leaked file descriptors
17317 if (intent != null && intent.hasFileDescriptors() == true) {
17318 throw new IllegalArgumentException("File descriptors passed in Intent");
17321 synchronized(this) {
17322 if (!(token instanceof ServiceRecord)) {
17323 throw new IllegalArgumentException("Invalid service token");
17325 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17329 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17330 // Refuse possible leaked file descriptors
17331 if (intent != null && intent.hasFileDescriptors() == true) {
17332 throw new IllegalArgumentException("File descriptors passed in Intent");
17335 synchronized(this) {
17336 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17340 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17341 synchronized(this) {
17342 if (!(token instanceof ServiceRecord)) {
17343 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17344 throw new IllegalArgumentException("Invalid service token");
17346 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17350 // =========================================================
17351 // BACKUP AND RESTORE
17352 // =========================================================
17354 // Cause the target app to be launched if necessary and its backup agent
17355 // instantiated. The backup agent will invoke backupAgentCreated() on the
17356 // activity manager to announce its creation.
17357 public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17358 if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17359 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17361 IPackageManager pm = AppGlobals.getPackageManager();
17362 ApplicationInfo app = null;
17364 app = pm.getApplicationInfo(packageName, 0, userId);
17365 } catch (RemoteException e) {
17366 // can't happen; package manager is process-local
17369 Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17373 synchronized(this) {
17374 // !!! TODO: currently no check here that we're already bound
17375 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17376 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17377 synchronized (stats) {
17378 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17381 // Backup agent is now in use, its package can't be stopped.
17383 AppGlobals.getPackageManager().setPackageStoppedState(
17384 app.packageName, false, UserHandle.getUserId(app.uid));
17385 } catch (RemoteException e) {
17386 } catch (IllegalArgumentException e) {
17387 Slog.w(TAG, "Failed trying to unstop package "
17388 + app.packageName + ": " + e);
17391 BackupRecord r = new BackupRecord(ss, app, backupMode);
17392 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17393 ? new ComponentName(app.packageName, app.backupAgentName)
17394 : new ComponentName("android", "FullBackupAgent");
17395 // startProcessLocked() returns existing proc's record if it's already running
17396 ProcessRecord proc = startProcessLocked(app.processName, app,
17397 false, 0, "backup", hostingName, false, false, false);
17398 if (proc == null) {
17399 Slog.e(TAG, "Unable to start backup agent process " + r);
17403 // If the app is a regular app (uid >= 10000) and not the system server or phone
17404 // process, etc, then mark it as being in full backup so that certain calls to the
17405 // process can be blocked. This is not reset to false anywhere because we kill the
17406 // process after the full backup is done and the ProcessRecord will vaporize anyway.
17407 if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17408 proc.inFullBackup = true;
17412 mBackupAppName = app.packageName;
17414 // Try not to kill the process during backup
17415 updateOomAdjLocked(proc);
17417 // If the process is already attached, schedule the creation of the backup agent now.
17418 // If it is not yet live, this will be done when it attaches to the framework.
17419 if (proc.thread != null) {
17420 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17422 proc.thread.scheduleCreateBackupAgent(app,
17423 compatibilityInfoForPackageLocked(app), backupMode);
17424 } catch (RemoteException e) {
17425 // Will time out on the backup manager side
17428 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17430 // Invariants: at this point, the target app process exists and the application
17431 // is either already running or in the process of coming up. mBackupTarget and
17432 // mBackupAppName describe the app, so that when it binds back to the AM we
17433 // know that it's scheduled for a backup-agent operation.
17440 public void clearPendingBackup() {
17441 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17442 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17444 synchronized (this) {
17445 mBackupTarget = null;
17446 mBackupAppName = null;
17450 // A backup agent has just come up
17451 public void backupAgentCreated(String agentPackageName, IBinder agent) {
17452 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17455 synchronized(this) {
17456 if (!agentPackageName.equals(mBackupAppName)) {
17457 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17462 long oldIdent = Binder.clearCallingIdentity();
17464 IBackupManager bm = IBackupManager.Stub.asInterface(
17465 ServiceManager.getService(Context.BACKUP_SERVICE));
17466 bm.agentConnected(agentPackageName, agent);
17467 } catch (RemoteException e) {
17468 // can't happen; the backup manager service is local
17469 } catch (Exception e) {
17470 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17471 e.printStackTrace();
17473 Binder.restoreCallingIdentity(oldIdent);
17477 // done with this agent
17478 public void unbindBackupAgent(ApplicationInfo appInfo) {
17479 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17480 if (appInfo == null) {
17481 Slog.w(TAG, "unbind backup agent for null app");
17485 synchronized(this) {
17487 if (mBackupAppName == null) {
17488 Slog.w(TAG, "Unbinding backup agent with no active backup");
17492 if (!mBackupAppName.equals(appInfo.packageName)) {
17493 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17497 // Not backing this app up any more; reset its OOM adjustment
17498 final ProcessRecord proc = mBackupTarget.app;
17499 updateOomAdjLocked(proc);
17501 // If the app crashed during backup, 'thread' will be null here
17502 if (proc.thread != null) {
17504 proc.thread.scheduleDestroyBackupAgent(appInfo,
17505 compatibilityInfoForPackageLocked(appInfo));
17506 } catch (Exception e) {
17507 Slog.e(TAG, "Exception when unbinding backup agent:");
17508 e.printStackTrace();
17512 mBackupTarget = null;
17513 mBackupAppName = null;
17517 // =========================================================
17519 // =========================================================
17521 boolean isPendingBroadcastProcessLocked(int pid) {
17522 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17523 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17526 void skipPendingBroadcastLocked(int pid) {
17527 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17528 for (BroadcastQueue queue : mBroadcastQueues) {
17529 queue.skipPendingBroadcastLocked(pid);
17533 // The app just attached; send any pending broadcasts that it should receive
17534 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17535 boolean didSomething = false;
17536 for (BroadcastQueue queue : mBroadcastQueues) {
17537 didSomething |= queue.sendPendingBroadcastsLocked(app);
17539 return didSomething;
17542 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17543 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17544 enforceNotIsolatedCaller("registerReceiver");
17545 ArrayList<Intent> stickyIntents = null;
17546 ProcessRecord callerApp = null;
17549 synchronized(this) {
17550 if (caller != null) {
17551 callerApp = getRecordForAppLocked(caller);
17552 if (callerApp == null) {
17553 throw new SecurityException(
17554 "Unable to find app for caller " + caller
17555 + " (pid=" + Binder.getCallingPid()
17556 + ") when registering receiver " + receiver);
17558 if (callerApp.info.uid != Process.SYSTEM_UID &&
17559 !callerApp.pkgList.containsKey(callerPackage) &&
17560 !"android".equals(callerPackage)) {
17561 throw new SecurityException("Given caller package " + callerPackage
17562 + " is not running in process " + callerApp);
17564 callingUid = callerApp.info.uid;
17565 callingPid = callerApp.pid;
17567 callerPackage = null;
17568 callingUid = Binder.getCallingUid();
17569 callingPid = Binder.getCallingPid();
17572 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17573 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17575 Iterator<String> actions = filter.actionsIterator();
17576 if (actions == null) {
17577 ArrayList<String> noAction = new ArrayList<String>(1);
17578 noAction.add(null);
17579 actions = noAction.iterator();
17582 // Collect stickies of users
17583 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17584 while (actions.hasNext()) {
17585 String action = actions.next();
17586 for (int id : userIds) {
17587 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17588 if (stickies != null) {
17589 ArrayList<Intent> intents = stickies.get(action);
17590 if (intents != null) {
17591 if (stickyIntents == null) {
17592 stickyIntents = new ArrayList<Intent>();
17594 stickyIntents.addAll(intents);
17601 ArrayList<Intent> allSticky = null;
17602 if (stickyIntents != null) {
17603 final ContentResolver resolver = mContext.getContentResolver();
17604 // Look for any matching sticky broadcasts...
17605 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17606 Intent intent = stickyIntents.get(i);
17607 // If intent has scheme "content", it will need to acccess
17608 // provider that needs to lock mProviderMap in ActivityThread
17609 // and also it may need to wait application response, so we
17610 // cannot lock ActivityManagerService here.
17611 if (filter.match(resolver, intent, true, TAG) >= 0) {
17612 if (allSticky == null) {
17613 allSticky = new ArrayList<Intent>();
17615 allSticky.add(intent);
17620 // The first sticky in the list is returned directly back to the client.
17621 Intent sticky = allSticky != null ? allSticky.get(0) : null;
17622 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17623 if (receiver == null) {
17627 synchronized (this) {
17628 if (callerApp != null && (callerApp.thread == null
17629 || callerApp.thread.asBinder() != caller.asBinder())) {
17630 // Original caller already died
17633 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17635 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17637 if (rl.app != null) {
17638 rl.app.receivers.add(rl);
17641 receiver.asBinder().linkToDeath(rl, 0);
17642 } catch (RemoteException e) {
17645 rl.linkedToDeath = true;
17647 mRegisteredReceivers.put(receiver.asBinder(), rl);
17648 } else if (rl.uid != callingUid) {
17649 throw new IllegalArgumentException(
17650 "Receiver requested to register for uid " + callingUid
17651 + " was previously registered for uid " + rl.uid);
17652 } else if (rl.pid != callingPid) {
17653 throw new IllegalArgumentException(
17654 "Receiver requested to register for pid " + callingPid
17655 + " was previously registered for pid " + rl.pid);
17656 } else if (rl.userId != userId) {
17657 throw new IllegalArgumentException(
17658 "Receiver requested to register for user " + userId
17659 + " was previously registered for user " + rl.userId);
17661 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17662 permission, callingUid, userId);
17664 if (!bf.debugCheck()) {
17665 Slog.w(TAG, "==> For Dynamic broadcast");
17667 mReceiverResolver.addFilter(bf);
17669 // Enqueue broadcasts for all existing stickies that match
17671 if (allSticky != null) {
17672 ArrayList receivers = new ArrayList();
17675 final int stickyCount = allSticky.size();
17676 for (int i = 0; i < stickyCount; i++) {
17677 Intent intent = allSticky.get(i);
17678 BroadcastQueue queue = broadcastQueueForIntent(intent);
17679 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17680 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17681 null, 0, null, null, false, true, true, -1);
17682 queue.enqueueParallelBroadcastLocked(r);
17683 queue.scheduleBroadcastsLocked();
17691 public void unregisterReceiver(IIntentReceiver receiver) {
17692 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17694 final long origId = Binder.clearCallingIdentity();
17696 boolean doTrim = false;
17698 synchronized(this) {
17699 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17701 final BroadcastRecord r = rl.curBroadcast;
17702 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17703 final boolean doNext = r.queue.finishReceiverLocked(
17704 r, r.resultCode, r.resultData, r.resultExtras,
17705 r.resultAbort, false);
17708 r.queue.processNextBroadcast(false);
17712 if (rl.app != null) {
17713 rl.app.receivers.remove(rl);
17715 removeReceiverLocked(rl);
17716 if (rl.linkedToDeath) {
17717 rl.linkedToDeath = false;
17718 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17723 // If we actually concluded any broadcasts, we might now be able
17724 // to trim the recipients' apps from our working set
17726 trimApplications();
17731 Binder.restoreCallingIdentity(origId);
17735 void removeReceiverLocked(ReceiverList rl) {
17736 mRegisteredReceivers.remove(rl.receiver.asBinder());
17737 for (int i = rl.size() - 1; i >= 0; i--) {
17738 mReceiverResolver.removeFilter(rl.get(i));
17742 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17743 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17744 ProcessRecord r = mLruProcesses.get(i);
17745 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17747 r.thread.dispatchPackageBroadcast(cmd, packages);
17748 } catch (RemoteException ex) {
17754 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17755 int callingUid, int[] users) {
17756 // TODO: come back and remove this assumption to triage all broadcasts
17757 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17759 List<ResolveInfo> receivers = null;
17761 HashSet<ComponentName> singleUserReceivers = null;
17762 boolean scannedFirstReceivers = false;
17763 for (int user : users) {
17764 // Skip users that have Shell restrictions, with exception of always permitted
17765 // Shell broadcasts
17766 if (callingUid == Process.SHELL_UID
17767 && mUserController.hasUserRestriction(
17768 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17769 && !isPermittedShellBroadcast(intent)) {
17772 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17773 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17774 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17775 // If this is not the system user, we need to check for
17776 // any receivers that should be filtered out.
17777 for (int i=0; i<newReceivers.size(); i++) {
17778 ResolveInfo ri = newReceivers.get(i);
17779 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17780 newReceivers.remove(i);
17785 if (newReceivers != null && newReceivers.size() == 0) {
17786 newReceivers = null;
17788 if (receivers == null) {
17789 receivers = newReceivers;
17790 } else if (newReceivers != null) {
17791 // We need to concatenate the additional receivers
17792 // found with what we have do far. This would be easy,
17793 // but we also need to de-dup any receivers that are
17795 if (!scannedFirstReceivers) {
17796 // Collect any single user receivers we had already retrieved.
17797 scannedFirstReceivers = true;
17798 for (int i=0; i<receivers.size(); i++) {
17799 ResolveInfo ri = receivers.get(i);
17800 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17801 ComponentName cn = new ComponentName(
17802 ri.activityInfo.packageName, ri.activityInfo.name);
17803 if (singleUserReceivers == null) {
17804 singleUserReceivers = new HashSet<ComponentName>();
17806 singleUserReceivers.add(cn);
17810 // Add the new results to the existing results, tracking
17811 // and de-dupping single user receivers.
17812 for (int i=0; i<newReceivers.size(); i++) {
17813 ResolveInfo ri = newReceivers.get(i);
17814 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17815 ComponentName cn = new ComponentName(
17816 ri.activityInfo.packageName, ri.activityInfo.name);
17817 if (singleUserReceivers == null) {
17818 singleUserReceivers = new HashSet<ComponentName>();
17820 if (!singleUserReceivers.contains(cn)) {
17821 singleUserReceivers.add(cn);
17830 } catch (RemoteException ex) {
17831 // pm is in same process, this will never happen.
17836 private boolean isPermittedShellBroadcast(Intent intent) {
17837 // remote bugreport should always be allowed to be taken
17838 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17841 private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17842 String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17843 final String action = intent.getAction();
17844 if (isProtectedBroadcast
17845 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17846 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17847 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17848 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17849 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17850 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17851 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17852 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17853 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17854 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17855 // Broadcast is either protected, or it's a public action that
17856 // we've relaxed, so it's fine for system internals to send.
17860 // This broadcast may be a problem... but there are often system components that
17861 // want to send an internal broadcast to themselves, which is annoying to have to
17862 // explicitly list each action as a protected broadcast, so we will check for that
17863 // one safe case and allow it: an explicit broadcast, only being received by something
17864 // that has protected itself.
17865 if (receivers != null && receivers.size() > 0
17866 && (intent.getPackage() != null || intent.getComponent() != null)) {
17867 boolean allProtected = true;
17868 for (int i = receivers.size()-1; i >= 0; i--) {
17869 Object target = receivers.get(i);
17870 if (target instanceof ResolveInfo) {
17871 ResolveInfo ri = (ResolveInfo)target;
17872 if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17873 allProtected = false;
17877 BroadcastFilter bf = (BroadcastFilter)target;
17878 if (bf.requiredPermission == null) {
17879 allProtected = false;
17884 if (allProtected) {
17890 // The vast majority of broadcasts sent from system internals
17891 // should be protected to avoid security holes, so yell loudly
17892 // to ensure we examine these cases.
17893 if (callerApp != null) {
17894 Log.wtf(TAG, "Sending non-protected broadcast " + action
17895 + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17898 Log.wtf(TAG, "Sending non-protected broadcast " + action
17899 + " from system uid " + UserHandle.formatUid(callingUid)
17900 + " pkg " + callerPackage,
17905 final int broadcastIntentLocked(ProcessRecord callerApp,
17906 String callerPackage, Intent intent, String resolvedType,
17907 IIntentReceiver resultTo, int resultCode, String resultData,
17908 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17909 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17910 intent = new Intent(intent);
17912 // By default broadcasts do not go to stopped apps.
17913 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17915 // If we have not finished booting, don't allow this to launch new processes.
17916 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17917 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17920 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17921 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17922 + " ordered=" + ordered + " userid=" + userId);
17923 if ((resultTo != null) && !ordered) {
17924 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17927 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17928 ALLOW_NON_FULL, "broadcast", callerPackage);
17930 // Make sure that the user who is receiving this broadcast is running.
17931 // If not, we will just skip it. Make an exception for shutdown broadcasts
17932 // and upgrade steps.
17934 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17935 if ((callingUid != Process.SYSTEM_UID
17936 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17937 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17938 Slog.w(TAG, "Skipping broadcast of " + intent
17939 + ": user " + userId + " is stopped");
17940 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17944 BroadcastOptions brOptions = null;
17945 if (bOptions != null) {
17946 brOptions = new BroadcastOptions(bOptions);
17947 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17948 // See if the caller is allowed to do this. Note we are checking against
17949 // the actual real caller (not whoever provided the operation as say a
17950 // PendingIntent), because that who is actually supplied the arguments.
17951 if (checkComponentPermission(
17952 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17953 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17954 != PackageManager.PERMISSION_GRANTED) {
17955 String msg = "Permission Denial: " + intent.getAction()
17956 + " broadcast from " + callerPackage + " (pid=" + callingPid
17957 + ", uid=" + callingUid + ")"
17959 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17961 throw new SecurityException(msg);
17966 // Verify that protected broadcasts are only being sent by system code,
17967 // and that system code is only sending protected broadcasts.
17968 final String action = intent.getAction();
17969 final boolean isProtectedBroadcast;
17971 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17972 } catch (RemoteException e) {
17973 Slog.w(TAG, "Remote exception", e);
17974 return ActivityManager.BROADCAST_SUCCESS;
17977 final boolean isCallerSystem;
17978 switch (UserHandle.getAppId(callingUid)) {
17979 case Process.ROOT_UID:
17980 case Process.SYSTEM_UID:
17981 case Process.PHONE_UID:
17982 case Process.BLUETOOTH_UID:
17983 case Process.NFC_UID:
17984 isCallerSystem = true;
17987 isCallerSystem = (callerApp != null) && callerApp.persistent;
17991 // First line security check before anything else: stop non-system apps from
17992 // sending protected broadcasts.
17993 if (!isCallerSystem) {
17994 if (isProtectedBroadcast) {
17995 String msg = "Permission Denial: not allowed to send broadcast "
17996 + action + " from pid="
17997 + callingPid + ", uid=" + callingUid;
17999 throw new SecurityException(msg);
18001 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18002 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18003 // Special case for compatibility: we don't want apps to send this,
18004 // but historically it has not been protected and apps may be using it
18005 // to poke their own app widget. So, instead of making it protected,
18006 // just limit it to the caller.
18007 if (callerPackage == null) {
18008 String msg = "Permission Denial: not allowed to send broadcast "
18009 + action + " from unknown caller.";
18011 throw new SecurityException(msg);
18012 } else if (intent.getComponent() != null) {
18013 // They are good enough to send to an explicit component... verify
18014 // it is being sent to the calling app.
18015 if (!intent.getComponent().getPackageName().equals(
18017 String msg = "Permission Denial: not allowed to send broadcast "
18019 + intent.getComponent().getPackageName() + " from "
18022 throw new SecurityException(msg);
18025 // Limit broadcast to their own package.
18026 intent.setPackage(callerPackage);
18031 if (action != null) {
18033 case Intent.ACTION_UID_REMOVED:
18034 case Intent.ACTION_PACKAGE_REMOVED:
18035 case Intent.ACTION_PACKAGE_CHANGED:
18036 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18037 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18038 case Intent.ACTION_PACKAGES_SUSPENDED:
18039 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18040 // Handle special intents: if this broadcast is from the package
18041 // manager about a package being removed, we need to remove all of
18042 // its activities from the history stack.
18043 if (checkComponentPermission(
18044 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18045 callingPid, callingUid, -1, true)
18046 != PackageManager.PERMISSION_GRANTED) {
18047 String msg = "Permission Denial: " + intent.getAction()
18048 + " broadcast from " + callerPackage + " (pid=" + callingPid
18049 + ", uid=" + callingUid + ")"
18051 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18053 throw new SecurityException(msg);
18056 case Intent.ACTION_UID_REMOVED:
18057 final Bundle intentExtras = intent.getExtras();
18058 final int uid = intentExtras != null
18059 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18061 mBatteryStatsService.removeUid(uid);
18062 mAppOpsService.uidRemoved(uid);
18065 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18066 // If resources are unavailable just force stop all those packages
18067 // and flush the attribute cache as well.
18069 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18070 if (list != null && list.length > 0) {
18071 for (int i = 0; i < list.length; i++) {
18072 forceStopPackageLocked(list[i], -1, false, true, true,
18073 false, false, userId, "storage unmount");
18075 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18076 sendPackageBroadcastLocked(
18077 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18081 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18082 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18084 case Intent.ACTION_PACKAGE_REMOVED:
18085 case Intent.ACTION_PACKAGE_CHANGED:
18086 Uri data = intent.getData();
18088 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18089 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18090 final boolean replacing =
18091 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18092 final boolean killProcess =
18093 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18094 final boolean fullUninstall = removed && !replacing;
18097 forceStopPackageLocked(ssp, UserHandle.getAppId(
18098 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18099 false, true, true, false, fullUninstall, userId,
18100 removed ? "pkg removed" : "pkg changed");
18102 final int cmd = killProcess
18103 ? IApplicationThread.PACKAGE_REMOVED
18104 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18105 sendPackageBroadcastLocked(cmd,
18106 new String[] {ssp}, userId);
18107 if (fullUninstall) {
18108 mAppOpsService.packageRemoved(
18109 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18111 // Remove all permissions granted from/to this package
18112 removeUriPermissionsForPackageLocked(ssp, userId, true);
18114 removeTasksByPackageNameLocked(ssp, userId);
18116 // Hide the "unsupported display" dialog if necessary.
18117 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18118 mUnsupportedDisplaySizeDialog.getPackageName())) {
18119 mUnsupportedDisplaySizeDialog.dismiss();
18120 mUnsupportedDisplaySizeDialog = null;
18122 mCompatModePackages.handlePackageUninstalledLocked(ssp);
18123 mBatteryStatsService.notePackageUninstalled(ssp);
18127 killPackageProcessesLocked(ssp, UserHandle.getAppId(
18128 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18129 userId, ProcessList.INVALID_ADJ,
18130 false, true, true, false, "change " + ssp);
18132 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18133 intent.getStringArrayExtra(
18134 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18138 case Intent.ACTION_PACKAGES_SUSPENDED:
18139 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18140 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18141 intent.getAction());
18142 final String[] packageNames = intent.getStringArrayExtra(
18143 Intent.EXTRA_CHANGED_PACKAGE_LIST);
18144 final int userHandle = intent.getIntExtra(
18145 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18147 synchronized(ActivityManagerService.this) {
18148 mRecentTasks.onPackagesSuspendedChanged(
18149 packageNames, suspended, userHandle);
18154 case Intent.ACTION_PACKAGE_REPLACED:
18156 final Uri data = intent.getData();
18158 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18159 final ApplicationInfo aInfo =
18160 getPackageManagerInternalLocked().getApplicationInfo(
18163 if (aInfo == null) {
18164 Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18165 + " ssp=" + ssp + " data=" + data);
18166 return ActivityManager.BROADCAST_SUCCESS;
18168 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18169 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18170 new String[] {ssp}, userId);
18174 case Intent.ACTION_PACKAGE_ADDED:
18176 // Special case for adding a package: by default turn on compatibility mode.
18177 Uri data = intent.getData();
18179 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18180 final boolean replacing =
18181 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18182 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18185 ApplicationInfo ai = AppGlobals.getPackageManager().
18186 getApplicationInfo(ssp, 0, 0);
18187 mBatteryStatsService.notePackageInstalled(ssp,
18188 ai != null ? ai.versionCode : 0);
18189 } catch (RemoteException e) {
18194 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18196 Uri data = intent.getData();
18198 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18199 // Hide the "unsupported display" dialog if necessary.
18200 if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18201 mUnsupportedDisplaySizeDialog.getPackageName())) {
18202 mUnsupportedDisplaySizeDialog.dismiss();
18203 mUnsupportedDisplaySizeDialog = null;
18205 mCompatModePackages.handlePackageDataClearedLocked(ssp);
18209 case Intent.ACTION_TIMEZONE_CHANGED:
18210 // If this is the time zone changed action, queue up a message that will reset
18211 // the timezone of all currently running processes. This message will get
18212 // queued up before the broadcast happens.
18213 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18215 case Intent.ACTION_TIME_CHANGED:
18216 // If the user set the time, let all running processes know.
18217 final int is24Hour =
18218 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18220 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18221 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18222 synchronized (stats) {
18223 stats.noteCurrentTimeChangedLocked();
18226 case Intent.ACTION_CLEAR_DNS_CACHE:
18227 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18229 case Proxy.PROXY_CHANGE_ACTION:
18230 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18231 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18233 case android.hardware.Camera.ACTION_NEW_PICTURE:
18234 case android.hardware.Camera.ACTION_NEW_VIDEO:
18235 // These broadcasts are no longer allowed by the system, since they can
18236 // cause significant thrashing at a crictical point (using the camera).
18237 // Apps should use JobScehduler to monitor for media provider changes.
18238 Slog.w(TAG, action + " no longer allowed; dropping from "
18239 + UserHandle.formatUid(callingUid));
18240 if (resultTo != null) {
18241 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18243 queue.performReceiveLocked(callerApp, resultTo, intent,
18244 Activity.RESULT_CANCELED, null, null,
18245 false, false, userId);
18246 } catch (RemoteException e) {
18247 Slog.w(TAG, "Failure ["
18248 + queue.mQueueName + "] sending broadcast result of "
18253 // Lie; we don't want to crash the app.
18254 return ActivityManager.BROADCAST_SUCCESS;
18258 // Add to the sticky list if requested.
18260 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18261 callingPid, callingUid)
18262 != PackageManager.PERMISSION_GRANTED) {
18263 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18264 + callingPid + ", uid=" + callingUid
18265 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18267 throw new SecurityException(msg);
18269 if (requiredPermissions != null && requiredPermissions.length > 0) {
18270 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18271 + " and enforce permissions " + Arrays.toString(requiredPermissions));
18272 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18274 if (intent.getComponent() != null) {
18275 throw new SecurityException(
18276 "Sticky broadcasts can't target a specific component");
18278 // We use userId directly here, since the "all" target is maintained
18279 // as a separate set of sticky broadcasts.
18280 if (userId != UserHandle.USER_ALL) {
18281 // But first, if this is not a broadcast to all users, then
18282 // make sure it doesn't conflict with an existing broadcast to
18284 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18285 UserHandle.USER_ALL);
18286 if (stickies != null) {
18287 ArrayList<Intent> list = stickies.get(intent.getAction());
18288 if (list != null) {
18289 int N = list.size();
18291 for (i=0; i<N; i++) {
18292 if (intent.filterEquals(list.get(i))) {
18293 throw new IllegalArgumentException(
18294 "Sticky broadcast " + intent + " for user "
18295 + userId + " conflicts with existing global broadcast");
18301 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18302 if (stickies == null) {
18303 stickies = new ArrayMap<>();
18304 mStickyBroadcasts.put(userId, stickies);
18306 ArrayList<Intent> list = stickies.get(intent.getAction());
18307 if (list == null) {
18308 list = new ArrayList<>();
18309 stickies.put(intent.getAction(), list);
18311 final int stickiesCount = list.size();
18313 for (i = 0; i < stickiesCount; i++) {
18314 if (intent.filterEquals(list.get(i))) {
18315 // This sticky already exists, replace it.
18316 list.set(i, new Intent(intent));
18320 if (i >= stickiesCount) {
18321 list.add(new Intent(intent));
18326 if (userId == UserHandle.USER_ALL) {
18327 // Caller wants broadcast to go to all started users.
18328 users = mUserController.getStartedUserArrayLocked();
18330 // Caller wants broadcast to go to one specific user.
18331 users = new int[] {userId};
18334 // Figure out who all will receive this broadcast.
18335 List receivers = null;
18336 List<BroadcastFilter> registeredReceivers = null;
18337 // Need to resolve the intent to interested receivers...
18338 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18340 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18342 if (intent.getComponent() == null) {
18343 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18344 // Query one target user at a time, excluding shell-restricted users
18345 for (int i = 0; i < users.length; i++) {
18346 if (mUserController.hasUserRestriction(
18347 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18350 List<BroadcastFilter> registeredReceiversForUser =
18351 mReceiverResolver.queryIntent(intent,
18352 resolvedType, false, users[i]);
18353 if (registeredReceivers == null) {
18354 registeredReceivers = registeredReceiversForUser;
18355 } else if (registeredReceiversForUser != null) {
18356 registeredReceivers.addAll(registeredReceiversForUser);
18360 registeredReceivers = mReceiverResolver.queryIntent(intent,
18361 resolvedType, false, userId);
18365 final boolean replacePending =
18366 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18368 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18369 + " replacePending=" + replacePending);
18371 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18372 if (!ordered && NR > 0) {
18373 // If we are not serializing this broadcast, then send the
18374 // registered receivers separately so they don't wait for the
18375 // components to be launched.
18376 if (isCallerSystem) {
18377 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18378 isProtectedBroadcast, registeredReceivers);
18380 final BroadcastQueue queue = broadcastQueueForIntent(intent);
18381 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18382 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18383 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18384 resultExtras, ordered, sticky, false, userId);
18385 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18386 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18388 queue.enqueueParallelBroadcastLocked(r);
18389 queue.scheduleBroadcastsLocked();
18391 registeredReceivers = null;
18395 // Merge into one list.
18397 if (receivers != null) {
18398 // A special case for PACKAGE_ADDED: do not allow the package
18399 // being added to see this broadcast. This prevents them from
18400 // using this as a back door to get run as soon as they are
18401 // installed. Maybe in the future we want to have a special install
18402 // broadcast or such for apps, but we'd like to deliberately make
18404 String skipPackages[] = null;
18405 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18406 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18407 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18408 Uri data = intent.getData();
18409 if (data != null) {
18410 String pkgName = data.getSchemeSpecificPart();
18411 if (pkgName != null) {
18412 skipPackages = new String[] { pkgName };
18415 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18416 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18418 if (skipPackages != null && (skipPackages.length > 0)) {
18419 for (String skipPackage : skipPackages) {
18420 if (skipPackage != null) {
18421 int NT = receivers.size();
18422 for (int it=0; it<NT; it++) {
18423 ResolveInfo curt = (ResolveInfo)receivers.get(it);
18424 if (curt.activityInfo.packageName.equals(skipPackage)) {
18425 receivers.remove(it);
18434 int NT = receivers != null ? receivers.size() : 0;
18436 ResolveInfo curt = null;
18437 BroadcastFilter curr = null;
18438 while (it < NT && ir < NR) {
18439 if (curt == null) {
18440 curt = (ResolveInfo)receivers.get(it);
18442 if (curr == null) {
18443 curr = registeredReceivers.get(ir);
18445 if (curr.getPriority() >= curt.priority) {
18446 // Insert this broadcast record into the final list.
18447 receivers.add(it, curr);
18453 // Skip to the next ResolveInfo in the final list.
18460 if (receivers == null) {
18461 receivers = new ArrayList();
18463 receivers.add(registeredReceivers.get(ir));
18467 if (isCallerSystem) {
18468 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18469 isProtectedBroadcast, receivers);
18472 if ((receivers != null && receivers.size() > 0)
18473 || resultTo != null) {
18474 BroadcastQueue queue = broadcastQueueForIntent(intent);
18475 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18476 callerPackage, callingPid, callingUid, resolvedType,
18477 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18478 resultData, resultExtras, ordered, sticky, false, userId);
18480 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18481 + ": prev had " + queue.mOrderedBroadcasts.size());
18482 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18483 "Enqueueing broadcast " + r.intent.getAction());
18485 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18487 queue.enqueueOrderedBroadcastLocked(r);
18488 queue.scheduleBroadcastsLocked();
18491 // There was nobody interested in the broadcast, but we still want to record
18492 // that it happened.
18493 if (intent.getComponent() == null && intent.getPackage() == null
18494 && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18495 // This was an implicit broadcast... let's record it for posterity.
18496 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18500 return ActivityManager.BROADCAST_SUCCESS;
18503 final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18504 int skipCount, long dispatchTime) {
18505 final long now = SystemClock.elapsedRealtime();
18506 if (mCurBroadcastStats == null ||
18507 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18508 mLastBroadcastStats = mCurBroadcastStats;
18509 if (mLastBroadcastStats != null) {
18510 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18511 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18513 mCurBroadcastStats = new BroadcastStats();
18515 mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18518 final Intent verifyBroadcastLocked(Intent intent) {
18519 // Refuse possible leaked file descriptors
18520 if (intent != null && intent.hasFileDescriptors() == true) {
18521 throw new IllegalArgumentException("File descriptors passed in Intent");
18524 int flags = intent.getFlags();
18526 if (!mProcessesReady) {
18527 // if the caller really truly claims to know what they're doing, go
18528 // ahead and allow the broadcast without launching any receivers
18529 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18530 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18531 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18532 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18533 + " before boot completion");
18534 throw new IllegalStateException("Cannot broadcast before boot completed");
18538 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18539 throw new IllegalArgumentException(
18540 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18546 public final int broadcastIntent(IApplicationThread caller,
18547 Intent intent, String resolvedType, IIntentReceiver resultTo,
18548 int resultCode, String resultData, Bundle resultExtras,
18549 String[] requiredPermissions, int appOp, Bundle bOptions,
18550 boolean serialized, boolean sticky, int userId) {
18551 enforceNotIsolatedCaller("broadcastIntent");
18552 synchronized(this) {
18553 intent = verifyBroadcastLocked(intent);
18555 final ProcessRecord callerApp = getRecordForAppLocked(caller);
18556 final int callingPid = Binder.getCallingPid();
18557 final int callingUid = Binder.getCallingUid();
18558 final long origId = Binder.clearCallingIdentity();
18559 int res = broadcastIntentLocked(callerApp,
18560 callerApp != null ? callerApp.info.packageName : null,
18561 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18562 requiredPermissions, appOp, bOptions, serialized, sticky,
18563 callingPid, callingUid, userId);
18564 Binder.restoreCallingIdentity(origId);
18570 int broadcastIntentInPackage(String packageName, int uid,
18571 Intent intent, String resolvedType, IIntentReceiver resultTo,
18572 int resultCode, String resultData, Bundle resultExtras,
18573 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18575 synchronized(this) {
18576 intent = verifyBroadcastLocked(intent);
18578 final long origId = Binder.clearCallingIdentity();
18579 String[] requiredPermissions = requiredPermission == null ? null
18580 : new String[] {requiredPermission};
18581 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18582 resultTo, resultCode, resultData, resultExtras,
18583 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18584 sticky, -1, uid, userId);
18585 Binder.restoreCallingIdentity(origId);
18590 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18591 // Refuse possible leaked file descriptors
18592 if (intent != null && intent.hasFileDescriptors() == true) {
18593 throw new IllegalArgumentException("File descriptors passed in Intent");
18596 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18597 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18599 synchronized(this) {
18600 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18601 != PackageManager.PERMISSION_GRANTED) {
18602 String msg = "Permission Denial: unbroadcastIntent() from pid="
18603 + Binder.getCallingPid()
18604 + ", uid=" + Binder.getCallingUid()
18605 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18607 throw new SecurityException(msg);
18609 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18610 if (stickies != null) {
18611 ArrayList<Intent> list = stickies.get(intent.getAction());
18612 if (list != null) {
18613 int N = list.size();
18615 for (i=0; i<N; i++) {
18616 if (intent.filterEquals(list.get(i))) {
18621 if (list.size() <= 0) {
18622 stickies.remove(intent.getAction());
18625 if (stickies.size() <= 0) {
18626 mStickyBroadcasts.remove(userId);
18632 void backgroundServicesFinishedLocked(int userId) {
18633 for (BroadcastQueue queue : mBroadcastQueues) {
18634 queue.backgroundServicesFinishedLocked(userId);
18638 public void finishReceiver(IBinder who, int resultCode, String resultData,
18639 Bundle resultExtras, boolean resultAbort, int flags) {
18640 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18642 // Refuse possible leaked file descriptors
18643 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18644 throw new IllegalArgumentException("File descriptors passed in Bundle");
18647 final long origId = Binder.clearCallingIdentity();
18649 boolean doNext = false;
18652 synchronized(this) {
18653 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18654 ? mFgBroadcastQueue : mBgBroadcastQueue;
18655 r = queue.getMatchingOrderedReceiver(who);
18657 doNext = r.queue.finishReceiverLocked(r, resultCode,
18658 resultData, resultExtras, resultAbort, true);
18663 r.queue.processNextBroadcast(false);
18665 trimApplications();
18667 Binder.restoreCallingIdentity(origId);
18671 // =========================================================
18673 // =========================================================
18675 public boolean startInstrumentation(ComponentName className,
18676 String profileFile, int flags, Bundle arguments,
18677 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18678 int userId, String abiOverride) {
18679 enforceNotIsolatedCaller("startInstrumentation");
18680 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18681 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18682 // Refuse possible leaked file descriptors
18683 if (arguments != null && arguments.hasFileDescriptors()) {
18684 throw new IllegalArgumentException("File descriptors passed in Bundle");
18687 synchronized(this) {
18688 InstrumentationInfo ii = null;
18689 ApplicationInfo ai = null;
18691 ii = mContext.getPackageManager().getInstrumentationInfo(
18692 className, STOCK_PM_FLAGS);
18693 ai = AppGlobals.getPackageManager().getApplicationInfo(
18694 ii.targetPackage, STOCK_PM_FLAGS, userId);
18695 } catch (PackageManager.NameNotFoundException e) {
18696 } catch (RemoteException e) {
18699 reportStartInstrumentationFailureLocked(watcher, className,
18700 "Unable to find instrumentation info for: " + className);
18704 reportStartInstrumentationFailureLocked(watcher, className,
18705 "Unable to find instrumentation target package: " + ii.targetPackage);
18708 if (!ai.hasCode()) {
18709 reportStartInstrumentationFailureLocked(watcher, className,
18710 "Instrumentation target has no code: " + ii.targetPackage);
18714 int match = mContext.getPackageManager().checkSignatures(
18715 ii.targetPackage, ii.packageName);
18716 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18717 String msg = "Permission Denial: starting instrumentation "
18718 + className + " from pid="
18719 + Binder.getCallingPid()
18720 + ", uid=" + Binder.getCallingPid()
18721 + " not allowed because package " + ii.packageName
18722 + " does not have a signature matching the target "
18723 + ii.targetPackage;
18724 reportStartInstrumentationFailureLocked(watcher, className, msg);
18725 throw new SecurityException(msg);
18728 final long origId = Binder.clearCallingIdentity();
18729 // Instrumentation can kill and relaunch even persistent processes
18730 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18732 ProcessRecord app = addAppLocked(ai, false, abiOverride);
18733 app.instrumentationClass = className;
18734 app.instrumentationInfo = ai;
18735 app.instrumentationProfileFile = profileFile;
18736 app.instrumentationArguments = arguments;
18737 app.instrumentationWatcher = watcher;
18738 app.instrumentationUiAutomationConnection = uiAutomationConnection;
18739 app.instrumentationResultClass = className;
18740 Binder.restoreCallingIdentity(origId);
18747 * Report errors that occur while attempting to start Instrumentation. Always writes the
18748 * error to the logs, but if somebody is watching, send the report there too. This enables
18749 * the "am" command to report errors with more information.
18751 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
18752 * @param cn The component name of the instrumentation.
18753 * @param report The error report.
18755 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18756 ComponentName cn, String report) {
18757 Slog.w(TAG, report);
18758 if (watcher != null) {
18759 Bundle results = new Bundle();
18760 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18761 results.putString("Error", report);
18762 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18766 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18767 if (app.instrumentationWatcher != null) {
18768 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18769 app.instrumentationClass, resultCode, results);
18772 // Can't call out of the system process with a lock held, so post a message.
18773 if (app.instrumentationUiAutomationConnection != null) {
18774 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18775 app.instrumentationUiAutomationConnection).sendToTarget();
18778 app.instrumentationWatcher = null;
18779 app.instrumentationUiAutomationConnection = null;
18780 app.instrumentationClass = null;
18781 app.instrumentationInfo = null;
18782 app.instrumentationProfileFile = null;
18783 app.instrumentationArguments = null;
18785 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18789 public void finishInstrumentation(IApplicationThread target,
18790 int resultCode, Bundle results) {
18791 int userId = UserHandle.getCallingUserId();
18792 // Refuse possible leaked file descriptors
18793 if (results != null && results.hasFileDescriptors()) {
18794 throw new IllegalArgumentException("File descriptors passed in Intent");
18797 synchronized(this) {
18798 ProcessRecord app = getRecordForAppLocked(target);
18800 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18803 final long origId = Binder.clearCallingIdentity();
18804 finishInstrumentationLocked(app, resultCode, results);
18805 Binder.restoreCallingIdentity(origId);
18809 // =========================================================
18811 // =========================================================
18813 public ConfigurationInfo getDeviceConfigurationInfo() {
18814 ConfigurationInfo config = new ConfigurationInfo();
18815 synchronized (this) {
18816 config.reqTouchScreen = mConfiguration.touchscreen;
18817 config.reqKeyboardType = mConfiguration.keyboard;
18818 config.reqNavigation = mConfiguration.navigation;
18819 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18820 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18821 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18823 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18824 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18825 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18827 config.reqGlEsVersion = GL_ES_VERSION;
18832 ActivityStack getFocusedStack() {
18833 return mStackSupervisor.getFocusedStack();
18837 public int getFocusedStackId() throws RemoteException {
18838 ActivityStack focusedStack = getFocusedStack();
18839 if (focusedStack != null) {
18840 return focusedStack.getStackId();
18845 public Configuration getConfiguration() {
18847 synchronized(this) {
18848 ci = new Configuration(mConfiguration);
18849 ci.userSetLocale = false;
18855 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18856 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18857 synchronized (this) {
18858 mSuppressResizeConfigChanges = suppress;
18863 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18864 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18865 if (fromStackId == HOME_STACK_ID) {
18866 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18868 synchronized (this) {
18869 final long origId = Binder.clearCallingIdentity();
18871 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18873 Binder.restoreCallingIdentity(origId);
18879 public void updatePersistentConfiguration(Configuration values) {
18880 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18881 "updateConfiguration()");
18882 enforceWriteSettingsPermission("updateConfiguration()");
18883 if (values == null) {
18884 throw new NullPointerException("Configuration must not be null");
18887 int userId = UserHandle.getCallingUserId();
18889 synchronized(this) {
18890 updatePersistentConfigurationLocked(values, userId);
18894 private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18895 final long origId = Binder.clearCallingIdentity();
18897 updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18899 Binder.restoreCallingIdentity(origId);
18903 private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18904 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18905 FONT_SCALE, 1.0f, userId);
18906 if (mConfiguration.fontScale != scaleFactor) {
18907 final Configuration configuration = mWindowManager.computeNewConfiguration();
18908 configuration.fontScale = scaleFactor;
18909 synchronized (this) {
18910 updatePersistentConfigurationLocked(configuration, userId);
18915 private void enforceWriteSettingsPermission(String func) {
18916 int uid = Binder.getCallingUid();
18917 if (uid == Process.ROOT_UID) {
18921 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18922 Settings.getPackageNameForUid(mContext, uid), false)) {
18926 String msg = "Permission Denial: " + func + " from pid="
18927 + Binder.getCallingPid()
18929 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18931 throw new SecurityException(msg);
18934 public void updateConfiguration(Configuration values) {
18935 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18936 "updateConfiguration()");
18938 synchronized(this) {
18939 if (values == null && mWindowManager != null) {
18940 // sentinel: fetch the current configuration from the window manager
18941 values = mWindowManager.computeNewConfiguration();
18944 if (mWindowManager != null) {
18945 mProcessList.applyDisplaySize(mWindowManager);
18948 final long origId = Binder.clearCallingIdentity();
18949 if (values != null) {
18950 Settings.System.clearConfiguration(values);
18952 updateConfigurationLocked(values, null, false);
18953 Binder.restoreCallingIdentity(origId);
18957 void updateUserConfigurationLocked() {
18958 Configuration configuration = new Configuration(mConfiguration);
18959 Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18960 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18961 updateConfigurationLocked(configuration, null, false);
18964 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18965 boolean initLocale) {
18966 return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18969 boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18970 boolean initLocale, boolean deferResume) {
18971 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18972 return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18973 UserHandle.USER_NULL, deferResume);
18976 // To cache the list of supported system locales
18977 private String[] mSupportedSystemLocales = null;
18980 * Do either or both things: (1) change the current configuration, and (2)
18981 * make sure the given activity is running with the (now) current
18982 * configuration. Returns true if the activity has been left running, or
18983 * false if <var>starting</var> is being destroyed to match the new
18986 * @param userId is only used when persistent parameter is set to true to persist configuration
18987 * for that particular user
18989 private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18990 boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18993 if (mWindowManager != null) {
18994 mWindowManager.deferSurfaceLayout();
18996 if (values != null) {
18997 Configuration newConfig = new Configuration(mConfiguration);
18998 changes = newConfig.updateFrom(values);
18999 if (changes != 0) {
19000 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19001 "Updating configuration to: " + values);
19003 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19005 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19006 final LocaleList locales = values.getLocales();
19007 int bestLocaleIndex = 0;
19008 if (locales.size() > 1) {
19009 if (mSupportedSystemLocales == null) {
19010 mSupportedSystemLocales =
19011 Resources.getSystem().getAssets().getLocales();
19013 bestLocaleIndex = Math.max(0,
19014 locales.getFirstMatchIndex(mSupportedSystemLocales));
19016 SystemProperties.set("persist.sys.locale",
19017 locales.get(bestLocaleIndex).toLanguageTag());
19018 LocaleList.setDefault(locales, bestLocaleIndex);
19019 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19020 locales.get(bestLocaleIndex)));
19023 mConfigurationSeq++;
19024 if (mConfigurationSeq <= 0) {
19025 mConfigurationSeq = 1;
19027 newConfig.seq = mConfigurationSeq;
19028 mConfiguration = newConfig;
19029 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19030 mUsageStatsService.reportConfigurationChange(newConfig,
19031 mUserController.getCurrentUserIdLocked());
19032 //mUsageStatsService.noteStartConfig(newConfig);
19034 final Configuration configCopy = new Configuration(mConfiguration);
19036 // TODO: If our config changes, should we auto dismiss any currently
19037 // showing dialogs?
19038 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19040 AttributeCache ac = AttributeCache.instance();
19042 ac.updateConfiguration(configCopy);
19045 // Make sure all resources in our process are updated
19046 // right now, so that anyone who is going to retrieve
19047 // resource values after we return will be sure to get
19048 // the new ones. This is especially important during
19049 // boot, where the first config change needs to guarantee
19050 // all resources have that config before following boot
19051 // code is executed.
19052 mSystemThread.applyConfigurationToResources(configCopy);
19054 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19055 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19056 msg.obj = new Configuration(configCopy);
19058 mHandler.sendMessage(msg);
19061 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19062 if (isDensityChange) {
19063 // Reset the unsupported display size dialog.
19064 mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19066 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19067 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19070 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19071 ProcessRecord app = mLruProcesses.get(i);
19073 if (app.thread != null) {
19074 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19075 + app.processName + " new config " + mConfiguration);
19076 app.thread.scheduleConfigurationChanged(configCopy);
19078 } catch (Exception e) {
19081 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19082 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19083 | Intent.FLAG_RECEIVER_REPLACE_PENDING
19084 | Intent.FLAG_RECEIVER_FOREGROUND);
19085 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19086 null, AppOpsManager.OP_NONE, null, false, false,
19087 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19088 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19089 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19090 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19091 if (!mProcessesReady) {
19092 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19094 broadcastIntentLocked(null, null, intent,
19095 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19096 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19099 // Update the configuration with WM first and check if any of the stacks need to be
19100 // resized due to the configuration change. If so, resize the stacks now and do any
19101 // relaunches if necessary. This way we don't need to relaunch again below in
19102 // ensureActivityConfigurationLocked().
19103 if (mWindowManager != null) {
19104 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19105 if (resizedStacks != null) {
19106 for (int stackId : resizedStacks) {
19107 final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19108 mStackSupervisor.resizeStackLocked(
19109 stackId, newBounds, null, null, false, false, deferResume);
19115 boolean kept = true;
19116 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19117 // mainStack is null during startup.
19118 if (mainStack != null) {
19119 if (changes != 0 && starting == null) {
19120 // If the configuration changed, and the caller is not already
19121 // in the process of starting an activity, then find the top
19122 // activity to check if its configuration needs to change.
19123 starting = mainStack.topRunningActivityLocked();
19126 if (starting != null) {
19127 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19128 // And we need to make sure at this point that all other activities
19129 // are made visible with the correct configuration.
19130 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19131 !PRESERVE_WINDOWS);
19134 if (mWindowManager != null) {
19135 mWindowManager.continueSurfaceLayout();
19141 * Decide based on the configuration whether we should shouw the ANR,
19142 * crash, etc dialogs. The idea is that if there is no affordence to
19143 * press the on-screen buttons, or the user experience would be more
19144 * greatly impacted than the crash itself, we shouldn't show the dialog.
19146 * A thought: SystemUI might also want to get told about this, the Power
19147 * dialog / global actions also might want different behaviors.
19149 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19150 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19151 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19152 && config.navigation == Configuration.NAVIGATION_NONAV);
19153 int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19154 final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19155 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19156 return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19160 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19161 synchronized (this) {
19162 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19163 if (srec != null) {
19164 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19170 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19171 Intent resultData) {
19173 synchronized (this) {
19174 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19176 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19182 public int getLaunchedFromUid(IBinder activityToken) {
19183 ActivityRecord srec;
19184 synchronized (this) {
19185 srec = ActivityRecord.forTokenLocked(activityToken);
19187 if (srec == null) {
19190 return srec.launchedFromUid;
19193 public String getLaunchedFromPackage(IBinder activityToken) {
19194 ActivityRecord srec;
19195 synchronized (this) {
19196 srec = ActivityRecord.forTokenLocked(activityToken);
19198 if (srec == null) {
19201 return srec.launchedFromPackage;
19204 // =========================================================
19205 // LIFETIME MANAGEMENT
19206 // =========================================================
19208 // Returns which broadcast queue the app is the current [or imminent] receiver
19209 // on, or 'null' if the app is not an active broadcast recipient.
19210 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19211 BroadcastRecord r = app.curReceiver;
19216 // It's not the current receiver, but it might be starting up to become one
19217 synchronized (this) {
19218 for (BroadcastQueue queue : mBroadcastQueues) {
19219 r = queue.mPendingBroadcast;
19220 if (r != null && r.curApp == app) {
19221 // found it; report which queue it's in
19230 Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19231 int targetUid, ComponentName targetComponent, String targetProcess) {
19232 if (!mTrackingAssociations) {
19235 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19236 = mAssociations.get(targetUid);
19237 if (components == null) {
19238 components = new ArrayMap<>();
19239 mAssociations.put(targetUid, components);
19241 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19242 if (sourceUids == null) {
19243 sourceUids = new SparseArray<>();
19244 components.put(targetComponent, sourceUids);
19246 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19247 if (sourceProcesses == null) {
19248 sourceProcesses = new ArrayMap<>();
19249 sourceUids.put(sourceUid, sourceProcesses);
19251 Association ass = sourceProcesses.get(sourceProcess);
19253 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19255 sourceProcesses.put(sourceProcess, ass);
19259 if (ass.mNesting == 1) {
19260 ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19261 ass.mLastState = sourceState;
19266 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19267 ComponentName targetComponent) {
19268 if (!mTrackingAssociations) {
19271 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19272 = mAssociations.get(targetUid);
19273 if (components == null) {
19276 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19277 if (sourceUids == null) {
19280 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19281 if (sourceProcesses == null) {
19284 Association ass = sourceProcesses.get(sourceProcess);
19285 if (ass == null || ass.mNesting <= 0) {
19289 if (ass.mNesting == 0) {
19290 long uptime = SystemClock.uptimeMillis();
19291 ass.mTime += uptime - ass.mStartTime;
19292 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19293 += uptime - ass.mLastStateUptime;
19294 ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19298 private void noteUidProcessState(final int uid, final int state) {
19299 mBatteryStatsService.noteUidProcessState(uid, state);
19300 if (mTrackingAssociations) {
19301 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19302 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19303 = mAssociations.valueAt(i1);
19304 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19305 SparseArray<ArrayMap<String, Association>> sourceUids
19306 = targetComponents.valueAt(i2);
19307 ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19308 if (sourceProcesses != null) {
19309 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19310 Association ass = sourceProcesses.valueAt(i4);
19311 if (ass.mNesting >= 1) {
19312 // currently associated
19313 long uptime = SystemClock.uptimeMillis();
19314 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19315 += uptime - ass.mLastStateUptime;
19316 ass.mLastState = state;
19317 ass.mLastStateUptime = uptime;
19326 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19327 boolean doingAll, long now) {
19328 if (mAdjSeq == app.adjSeq) {
19329 // This adjustment has already been computed.
19330 return app.curRawAdj;
19333 if (app.thread == null) {
19334 app.adjSeq = mAdjSeq;
19335 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19336 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19337 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19340 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19341 app.adjSource = null;
19342 app.adjTarget = null;
19344 app.cached = false;
19346 final int activitiesSize = app.activities.size();
19348 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19349 // The max adjustment doesn't allow this app to be anything
19350 // below foreground, so it is not worth doing work for it.
19351 app.adjType = "fixed";
19352 app.adjSeq = mAdjSeq;
19353 app.curRawAdj = app.maxAdj;
19354 app.foregroundActivities = false;
19355 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19356 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19357 // System processes can do UI, and when they do we want to have
19358 // them trim their memory after the user leaves the UI. To
19359 // facilitate this, here we need to determine whether or not it
19360 // is currently showing UI.
19361 app.systemNoUi = true;
19362 if (app == TOP_APP) {
19363 app.systemNoUi = false;
19364 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19365 app.adjType = "pers-top-activity";
19366 } else if (app.hasTopUi) {
19367 app.systemNoUi = false;
19368 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19369 app.adjType = "pers-top-ui";
19370 } else if (activitiesSize > 0) {
19371 for (int j = 0; j < activitiesSize; j++) {
19372 final ActivityRecord r = app.activities.get(j);
19374 app.systemNoUi = false;
19378 if (!app.systemNoUi) {
19379 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19381 return (app.curAdj=app.maxAdj);
19384 app.systemNoUi = false;
19386 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19388 // Determine the importance of the process, starting with most
19389 // important to least, and assign an appropriate OOM adjustment.
19393 boolean foregroundActivities = false;
19394 BroadcastQueue queue;
19395 if (app == TOP_APP) {
19396 // The last app on the list is the foreground app.
19397 adj = ProcessList.FOREGROUND_APP_ADJ;
19398 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19399 app.adjType = "top-activity";
19400 foregroundActivities = true;
19401 procState = PROCESS_STATE_CUR_TOP;
19402 } else if (app.instrumentationClass != null) {
19403 // Don't want to kill running instrumentation.
19404 adj = ProcessList.FOREGROUND_APP_ADJ;
19405 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19406 app.adjType = "instrumentation";
19407 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19408 } else if ((queue = isReceivingBroadcast(app)) != null) {
19409 // An app that is currently receiving a broadcast also
19410 // counts as being in the foreground for OOM killer purposes.
19411 // It's placed in a sched group based on the nature of the
19412 // broadcast as reflected by which queue it's active in.
19413 adj = ProcessList.FOREGROUND_APP_ADJ;
19414 schedGroup = (queue == mFgBroadcastQueue)
19415 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19416 app.adjType = "broadcast";
19417 procState = ActivityManager.PROCESS_STATE_RECEIVER;
19418 } else if (app.executingServices.size() > 0) {
19419 // An app that is currently executing a service callback also
19420 // counts as being in the foreground.
19421 adj = ProcessList.FOREGROUND_APP_ADJ;
19422 schedGroup = app.execServicesFg ?
19423 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19424 app.adjType = "exec-service";
19425 procState = ActivityManager.PROCESS_STATE_SERVICE;
19426 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19428 // As far as we know the process is empty. We may change our mind later.
19429 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19430 // At this point we don't actually know the adjustment. Use the cached adj
19431 // value that the caller wants us to.
19433 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19436 app.adjType = "cch-empty";
19439 // Examine all activities if not already foreground.
19440 if (!foregroundActivities && activitiesSize > 0) {
19441 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19442 for (int j = 0; j < activitiesSize; j++) {
19443 final ActivityRecord r = app.activities.get(j);
19444 if (r.app != app) {
19445 Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19446 + " instead of expected " + app);
19447 if (r.app == null || (r.app.uid == app.uid)) {
19448 // Only fix things up when they look sane
19455 // App has a visible activity; only upgrade adjustment.
19456 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19457 adj = ProcessList.VISIBLE_APP_ADJ;
19458 app.adjType = "visible";
19460 if (procState > PROCESS_STATE_CUR_TOP) {
19461 procState = PROCESS_STATE_CUR_TOP;
19463 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19464 app.cached = false;
19466 foregroundActivities = true;
19467 if (r.task != null && minLayer > 0) {
19468 final int layer = r.task.mLayerRank;
19469 if (layer >= 0 && minLayer > layer) {
19474 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19475 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19476 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19477 app.adjType = "pausing";
19479 if (procState > PROCESS_STATE_CUR_TOP) {
19480 procState = PROCESS_STATE_CUR_TOP;
19482 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19483 app.cached = false;
19485 foregroundActivities = true;
19486 } else if (r.state == ActivityState.STOPPING) {
19487 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19488 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19489 app.adjType = "stopping";
19491 // For the process state, we will at this point consider the
19492 // process to be cached. It will be cached either as an activity
19493 // or empty depending on whether the activity is finishing. We do
19494 // this so that we can treat the process as cached for purposes of
19495 // memory trimming (determing current memory level, trim command to
19496 // send to process) since there can be an arbitrary number of stopping
19497 // processes and they should soon all go into the cached state.
19498 if (!r.finishing) {
19499 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19500 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19503 app.cached = false;
19505 foregroundActivities = true;
19507 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19508 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19509 app.adjType = "cch-act";
19513 if (adj == ProcessList.VISIBLE_APP_ADJ) {
19518 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19519 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19520 if (app.foregroundServices) {
19521 // The user is aware of this app, so make it visible.
19522 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19523 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19524 app.cached = false;
19525 app.adjType = "fg-service";
19526 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19527 } else if (app.forcingToForeground != null) {
19528 // The user is aware of this app, so make it visible.
19529 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19530 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19531 app.cached = false;
19532 app.adjType = "force-fg";
19533 app.adjSource = app.forcingToForeground;
19534 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19538 if (app == mHeavyWeightProcess) {
19539 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19540 // We don't want to kill the current heavy-weight process.
19541 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19542 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19543 app.cached = false;
19544 app.adjType = "heavy";
19546 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19547 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19551 if (app == mHomeProcess) {
19552 if (adj > ProcessList.HOME_APP_ADJ) {
19553 // This process is hosting what we currently consider to be the
19554 // home app, so we don't want to let it go into the background.
19555 adj = ProcessList.HOME_APP_ADJ;
19556 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19557 app.cached = false;
19558 app.adjType = "home";
19560 if (procState > ActivityManager.PROCESS_STATE_HOME) {
19561 procState = ActivityManager.PROCESS_STATE_HOME;
19565 if (app == mPreviousProcess && app.activities.size() > 0) {
19566 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19567 // This was the previous process that showed UI to the user.
19568 // We want to try to keep it around more aggressively, to give
19569 // a good experience around switching between two apps.
19570 adj = ProcessList.PREVIOUS_APP_ADJ;
19571 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19572 app.cached = false;
19573 app.adjType = "previous";
19575 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19576 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19580 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19581 + " reason=" + app.adjType);
19583 // By default, we use the computed adjustment. It may be changed if
19584 // there are applications dependent on our services or providers, but
19585 // this gives us a baseline and makes sure we don't get into an
19586 // infinite recursion.
19587 app.adjSeq = mAdjSeq;
19588 app.curRawAdj = adj;
19589 app.hasStartedServices = false;
19591 if (mBackupTarget != null && app == mBackupTarget.app) {
19592 // If possible we want to avoid killing apps while they're being backed up
19593 if (adj > ProcessList.BACKUP_APP_ADJ) {
19594 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19595 adj = ProcessList.BACKUP_APP_ADJ;
19596 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19597 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19599 app.adjType = "backup";
19600 app.cached = false;
19602 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19603 procState = ActivityManager.PROCESS_STATE_BACKUP;
19607 boolean mayBeTop = false;
19609 for (int is = app.services.size()-1;
19610 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19611 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19612 || procState > ActivityManager.PROCESS_STATE_TOP);
19614 ServiceRecord s = app.services.valueAt(is);
19615 if (s.startRequested) {
19616 app.hasStartedServices = true;
19617 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19618 procState = ActivityManager.PROCESS_STATE_SERVICE;
19620 if (app.hasShownUi && app != mHomeProcess) {
19621 // If this process has shown some UI, let it immediately
19622 // go to the LRU list because it may be pretty heavy with
19623 // UI stuff. We'll tag it with a label just to help
19624 // debug and understand what is going on.
19625 if (adj > ProcessList.SERVICE_ADJ) {
19626 app.adjType = "cch-started-ui-services";
19629 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19630 // This service has seen some activity within
19631 // recent memory, so we will keep its process ahead
19632 // of the background processes.
19633 if (adj > ProcessList.SERVICE_ADJ) {
19634 adj = ProcessList.SERVICE_ADJ;
19635 app.adjType = "started-services";
19636 app.cached = false;
19639 // If we have let the service slide into the background
19640 // state, still have some text describing what it is doing
19641 // even though the service no longer has an impact.
19642 if (adj > ProcessList.SERVICE_ADJ) {
19643 app.adjType = "cch-started-services";
19648 for (int conni = s.connections.size()-1;
19649 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19650 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19651 || procState > ActivityManager.PROCESS_STATE_TOP);
19653 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19655 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19656 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19657 || procState > ActivityManager.PROCESS_STATE_TOP);
19659 // XXX should compute this based on the max of
19660 // all connected clients.
19661 ConnectionRecord cr = clist.get(i);
19662 if (cr.binding.client == app) {
19663 // Binding to ourself is not interesting.
19667 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19668 ProcessRecord client = cr.binding.client;
19669 int clientAdj = computeOomAdjLocked(client, cachedAdj,
19670 TOP_APP, doingAll, now);
19671 int clientProcState = client.curProcState;
19672 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19673 // If the other app is cached for any reason, for purposes here
19674 // we are going to consider it empty. The specific cached state
19675 // doesn't propagate except under certain conditions.
19676 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19678 String adjType = null;
19679 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19680 // Not doing bind OOM management, so treat
19681 // this guy more like a started service.
19682 if (app.hasShownUi && app != mHomeProcess) {
19683 // If this process has shown some UI, let it immediately
19684 // go to the LRU list because it may be pretty heavy with
19685 // UI stuff. We'll tag it with a label just to help
19686 // debug and understand what is going on.
19687 if (adj > clientAdj) {
19688 adjType = "cch-bound-ui-services";
19690 app.cached = false;
19692 clientProcState = procState;
19694 if (now >= (s.lastActivity
19695 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19696 // This service has not seen activity within
19697 // recent memory, so allow it to drop to the
19698 // LRU list if there is no other reason to keep
19699 // it around. We'll also tag it with a label just
19700 // to help debug and undertand what is going on.
19701 if (adj > clientAdj) {
19702 adjType = "cch-bound-services";
19708 if (adj > clientAdj) {
19709 // If this process has recently shown UI, and
19710 // the process that is binding to it is less
19711 // important than being visible, then we don't
19712 // care about the binding as much as we care
19713 // about letting this process get into the LRU
19714 // list to be killed and restarted if needed for
19716 if (app.hasShownUi && app != mHomeProcess
19717 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19718 adjType = "cch-bound-ui-services";
19720 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19721 |Context.BIND_IMPORTANT)) != 0) {
19722 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19723 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19724 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19725 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19726 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19727 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19728 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19731 if (adj > ProcessList.VISIBLE_APP_ADJ) {
19732 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19735 if (!client.cached) {
19736 app.cached = false;
19738 adjType = "service";
19741 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19742 // This will treat important bound services identically to
19743 // the top app, which may behave differently than generic
19744 // foreground work.
19745 if (client.curSchedGroup > schedGroup) {
19746 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19747 schedGroup = client.curSchedGroup;
19749 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19752 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19753 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19754 // Special handling of clients who are in the top state.
19755 // We *may* want to consider this process to be in the
19756 // top state as well, but only if there is not another
19757 // reason for it to be running. Being on the top is a
19758 // special state, meaning you are specifically running
19759 // for the current top app. If the process is already
19760 // running in the background for some other reason, it
19761 // is more important to continue considering it to be
19762 // in the background state.
19764 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19766 // Special handling for above-top states (persistent
19767 // processes). These should not bring the current process
19768 // into the top state, since they are not on top. Instead
19769 // give them the best state after that.
19770 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19772 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19773 } else if (mWakefulness
19774 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19775 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19778 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19781 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19786 if (clientProcState <
19787 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19789 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19792 if (procState > clientProcState) {
19793 procState = clientProcState;
19795 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19796 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19797 app.pendingUiClean = true;
19799 if (adjType != null) {
19800 app.adjType = adjType;
19801 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19802 .REASON_SERVICE_IN_USE;
19803 app.adjSource = cr.binding.client;
19804 app.adjSourceProcState = clientProcState;
19805 app.adjTarget = s.name;
19808 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19809 app.treatLikeActivity = true;
19811 final ActivityRecord a = cr.activity;
19812 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19813 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19814 (a.visible || a.state == ActivityState.RESUMED ||
19815 a.state == ActivityState.PAUSING)) {
19816 adj = ProcessList.FOREGROUND_APP_ADJ;
19817 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19818 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19819 schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19821 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19824 app.cached = false;
19825 app.adjType = "service";
19826 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19827 .REASON_SERVICE_IN_USE;
19829 app.adjSourceProcState = procState;
19830 app.adjTarget = s.name;
19837 for (int provi = app.pubProviders.size()-1;
19838 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19839 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19840 || procState > ActivityManager.PROCESS_STATE_TOP);
19842 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19843 for (int i = cpr.connections.size()-1;
19844 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19845 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19846 || procState > ActivityManager.PROCESS_STATE_TOP);
19848 ContentProviderConnection conn = cpr.connections.get(i);
19849 ProcessRecord client = conn.client;
19850 if (client == app) {
19851 // Being our own client is not interesting.
19854 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19855 int clientProcState = client.curProcState;
19856 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19857 // If the other app is cached for any reason, for purposes here
19858 // we are going to consider it empty.
19859 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19861 if (adj > clientAdj) {
19862 if (app.hasShownUi && app != mHomeProcess
19863 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19864 app.adjType = "cch-ui-provider";
19866 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19867 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19868 app.adjType = "provider";
19870 app.cached &= client.cached;
19871 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19872 .REASON_PROVIDER_IN_USE;
19873 app.adjSource = client;
19874 app.adjSourceProcState = clientProcState;
19875 app.adjTarget = cpr.name;
19877 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19878 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19879 // Special handling of clients who are in the top state.
19880 // We *may* want to consider this process to be in the
19881 // top state as well, but only if there is not another
19882 // reason for it to be running. Being on the top is a
19883 // special state, meaning you are specifically running
19884 // for the current top app. If the process is already
19885 // running in the background for some other reason, it
19886 // is more important to continue considering it to be
19887 // in the background state.
19889 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19891 // Special handling for above-top states (persistent
19892 // processes). These should not bring the current process
19893 // into the top state, since they are not on top. Instead
19894 // give them the best state after that.
19896 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19899 if (procState > clientProcState) {
19900 procState = clientProcState;
19902 if (client.curSchedGroup > schedGroup) {
19903 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19906 // If the provider has external (non-framework) process
19907 // dependencies, ensure that its adjustment is at least
19908 // FOREGROUND_APP_ADJ.
19909 if (cpr.hasExternalProcessHandles()) {
19910 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19911 adj = ProcessList.FOREGROUND_APP_ADJ;
19912 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19913 app.cached = false;
19914 app.adjType = "provider";
19915 app.adjTarget = cpr.name;
19917 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19918 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19923 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19924 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19925 adj = ProcessList.PREVIOUS_APP_ADJ;
19926 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19927 app.cached = false;
19928 app.adjType = "provider";
19930 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19931 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19935 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19936 // A client of one of our services or providers is in the top state. We
19937 // *may* want to be in the top state, but not if we are already running in
19938 // the background for some other reason. For the decision here, we are going
19939 // to pick out a few specific states that we want to remain in when a client
19940 // is top (states that tend to be longer-term) and otherwise allow it to go
19941 // to the top state.
19942 switch (procState) {
19943 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19944 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19945 case ActivityManager.PROCESS_STATE_SERVICE:
19946 // These all are longer-term states, so pull them up to the top
19947 // of the background states, but not all the way to the top state.
19948 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19951 // Otherwise, top is a better choice, so take it.
19952 procState = ActivityManager.PROCESS_STATE_TOP;
19957 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19958 if (app.hasClientActivities) {
19959 // This is a cached process, but with client activities. Mark it so.
19960 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19961 app.adjType = "cch-client-act";
19962 } else if (app.treatLikeActivity) {
19963 // This is a cached process, but somebody wants us to treat it like it has
19964 // an activity, okay!
19965 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19966 app.adjType = "cch-as-act";
19970 if (adj == ProcessList.SERVICE_ADJ) {
19972 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19973 mNewNumServiceProcs++;
19974 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19975 if (!app.serviceb) {
19976 // This service isn't far enough down on the LRU list to
19977 // normally be a B service, but if we are low on RAM and it
19978 // is large we want to force it down since we would prefer to
19979 // keep launcher over it.
19980 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19981 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19982 app.serviceHighRam = true;
19983 app.serviceb = true;
19984 //Slog.i(TAG, "ADJ " + app + " high ram!");
19986 mNewNumAServiceProcs++;
19987 //Slog.i(TAG, "ADJ " + app + " not high ram!");
19990 app.serviceHighRam = false;
19993 if (app.serviceb) {
19994 adj = ProcessList.SERVICE_B_ADJ;
19998 app.curRawAdj = adj;
20000 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20001 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20002 if (adj > app.maxAdj) {
20004 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20005 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20009 // Do final modification to adj. Everything we do between here and applying
20010 // the final setAdj must be done in this function, because we will also use
20011 // it when computing the final cached adj later. Note that we don't need to
20012 // worry about this for max adj above, since max adj will always be used to
20013 // keep it out of the cached vaues.
20014 app.curAdj = app.modifyRawOomAdj(adj);
20015 app.curSchedGroup = schedGroup;
20016 app.curProcState = procState;
20017 app.foregroundActivities = foregroundActivities;
20019 return app.curRawAdj;
20023 * Record new PSS sample for a process.
20025 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20027 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20029 proc.lastPssTime = now;
20030 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20031 if (DEBUG_PSS) Slog.d(TAG_PSS,
20032 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20033 + " state=" + ProcessList.makeProcStateString(procState));
20034 if (proc.initialIdlePss == 0) {
20035 proc.initialIdlePss = pss;
20037 proc.lastPss = pss;
20038 proc.lastSwapPss = swapPss;
20039 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20040 proc.lastCachedPss = pss;
20041 proc.lastCachedSwapPss = swapPss;
20044 final SparseArray<Pair<Long, String>> watchUids
20045 = mMemWatchProcesses.getMap().get(proc.processName);
20047 if (watchUids != null) {
20048 Pair<Long, String> val = watchUids.get(proc.uid);
20050 val = watchUids.get(0);
20056 if (check != null) {
20057 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20058 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20059 if (!isDebuggable) {
20060 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20061 isDebuggable = true;
20064 if (isDebuggable) {
20065 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20066 final ProcessRecord myProc = proc;
20067 final File heapdumpFile = DumpHeapProvider.getJavaFile();
20068 mMemWatchDumpProcName = proc.processName;
20069 mMemWatchDumpFile = heapdumpFile.toString();
20070 mMemWatchDumpPid = proc.pid;
20071 mMemWatchDumpUid = proc.uid;
20072 BackgroundThread.getHandler().post(new Runnable() {
20074 public void run() {
20075 revokeUriPermission(ActivityThread.currentActivityThread()
20076 .getApplicationThread(),
20077 DumpHeapActivity.JAVA_URI,
20078 Intent.FLAG_GRANT_READ_URI_PERMISSION
20079 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20080 UserHandle.myUserId());
20081 ParcelFileDescriptor fd = null;
20083 heapdumpFile.delete();
20084 fd = ParcelFileDescriptor.open(heapdumpFile,
20085 ParcelFileDescriptor.MODE_CREATE |
20086 ParcelFileDescriptor.MODE_TRUNCATE |
20087 ParcelFileDescriptor.MODE_WRITE_ONLY |
20088 ParcelFileDescriptor.MODE_APPEND);
20089 IApplicationThread thread = myProc.thread;
20090 if (thread != null) {
20092 if (DEBUG_PSS) Slog.d(TAG_PSS,
20093 "Requesting dump heap from "
20094 + myProc + " to " + heapdumpFile);
20095 thread.dumpHeap(true, heapdumpFile.toString(), fd);
20096 } catch (RemoteException e) {
20099 } catch (FileNotFoundException e) {
20100 e.printStackTrace();
20105 } catch (IOException e) {
20112 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20113 + ", but debugging not enabled");
20120 * Schedule PSS collection of a process.
20122 void requestPssLocked(ProcessRecord proc, int procState) {
20123 if (mPendingPssProcesses.contains(proc)) {
20126 if (mPendingPssProcesses.size() == 0) {
20127 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20129 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20130 proc.pssProcState = procState;
20131 mPendingPssProcesses.add(proc);
20135 * Schedule PSS collection of all processes.
20137 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20139 if (now < (mLastFullPssTime +
20140 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20144 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
20145 mLastFullPssTime = now;
20146 mFullPssPending = true;
20147 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20148 mPendingPssProcesses.clear();
20149 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20150 ProcessRecord app = mLruProcesses.get(i);
20151 if (app.thread == null
20152 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20155 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20156 app.pssProcState = app.setProcState;
20157 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20158 mTestPssMode, isSleepingLocked(), now);
20159 mPendingPssProcesses.add(app);
20162 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20165 public void setTestPssMode(boolean enabled) {
20166 synchronized (this) {
20167 mTestPssMode = enabled;
20169 // Whenever we enable the mode, we want to take a snapshot all of current
20170 // process mem use.
20171 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20177 * Ask a given process to GC right now.
20179 final void performAppGcLocked(ProcessRecord app) {
20181 app.lastRequestedGc = SystemClock.uptimeMillis();
20182 if (app.thread != null) {
20183 if (app.reportLowMemory) {
20184 app.reportLowMemory = false;
20185 app.thread.scheduleLowMemory();
20187 app.thread.processInBackground();
20190 } catch (Exception e) {
20196 * Returns true if things are idle enough to perform GCs.
20198 private final boolean canGcNowLocked() {
20199 boolean processingBroadcasts = false;
20200 for (BroadcastQueue q : mBroadcastQueues) {
20201 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20202 processingBroadcasts = true;
20205 return !processingBroadcasts
20206 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20210 * Perform GCs on all processes that are waiting for it, but only
20211 * if things are idle.
20213 final void performAppGcsLocked() {
20214 final int N = mProcessesToGc.size();
20218 if (canGcNowLocked()) {
20219 while (mProcessesToGc.size() > 0) {
20220 ProcessRecord proc = mProcessesToGc.remove(0);
20221 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20222 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20223 <= SystemClock.uptimeMillis()) {
20224 // To avoid spamming the system, we will GC processes one
20225 // at a time, waiting a few seconds between each.
20226 performAppGcLocked(proc);
20227 scheduleAppGcsLocked();
20230 // It hasn't been long enough since we last GCed this
20231 // process... put it in the list to wait for its time.
20232 addProcessToGcListLocked(proc);
20238 scheduleAppGcsLocked();
20243 * If all looks good, perform GCs on all processes waiting for them.
20245 final void performAppGcsIfAppropriateLocked() {
20246 if (canGcNowLocked()) {
20247 performAppGcsLocked();
20250 // Still not idle, wait some more.
20251 scheduleAppGcsLocked();
20255 * Schedule the execution of all pending app GCs.
20257 final void scheduleAppGcsLocked() {
20258 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20260 if (mProcessesToGc.size() > 0) {
20261 // Schedule a GC for the time to the next process.
20262 ProcessRecord proc = mProcessesToGc.get(0);
20263 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20265 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20266 long now = SystemClock.uptimeMillis();
20267 if (when < (now+GC_TIMEOUT)) {
20268 when = now + GC_TIMEOUT;
20270 mHandler.sendMessageAtTime(msg, when);
20275 * Add a process to the array of processes waiting to be GCed. Keeps the
20276 * list in sorted order by the last GC time. The process can't already be
20279 final void addProcessToGcListLocked(ProcessRecord proc) {
20280 boolean added = false;
20281 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20282 if (mProcessesToGc.get(i).lastRequestedGc <
20283 proc.lastRequestedGc) {
20285 mProcessesToGc.add(i+1, proc);
20290 mProcessesToGc.add(0, proc);
20295 * Set up to ask a process to GC itself. This will either do it
20296 * immediately, or put it on the list of processes to gc the next
20297 * time things are idle.
20299 final void scheduleAppGcLocked(ProcessRecord app) {
20300 long now = SystemClock.uptimeMillis();
20301 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20304 if (!mProcessesToGc.contains(app)) {
20305 addProcessToGcListLocked(app);
20306 scheduleAppGcsLocked();
20310 final void checkExcessivePowerUsageLocked(boolean doKills) {
20311 updateCpuStatsNow();
20313 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20314 boolean doWakeKills = doKills;
20315 boolean doCpuKills = doKills;
20316 if (mLastPowerCheckRealtime == 0) {
20317 doWakeKills = false;
20319 if (mLastPowerCheckUptime == 0) {
20320 doCpuKills = false;
20322 if (stats.isScreenOn()) {
20323 doWakeKills = false;
20325 final long curRealtime = SystemClock.elapsedRealtime();
20326 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20327 final long curUptime = SystemClock.uptimeMillis();
20328 final long uptimeSince = curUptime - mLastPowerCheckUptime;
20329 mLastPowerCheckRealtime = curRealtime;
20330 mLastPowerCheckUptime = curUptime;
20331 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20332 doWakeKills = false;
20334 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20335 doCpuKills = false;
20337 int i = mLruProcesses.size();
20340 ProcessRecord app = mLruProcesses.get(i);
20341 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20343 synchronized (stats) {
20344 wtime = stats.getProcessWakeTime(app.info.uid,
20345 app.pid, curRealtime);
20347 long wtimeUsed = wtime - app.lastWakeTime;
20348 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20350 StringBuilder sb = new StringBuilder(128);
20351 sb.append("Wake for ");
20352 app.toShortString(sb);
20353 sb.append(": over ");
20354 TimeUtils.formatDuration(realtimeSince, sb);
20355 sb.append(" used ");
20356 TimeUtils.formatDuration(wtimeUsed, sb);
20358 sb.append((wtimeUsed*100)/realtimeSince);
20360 Slog.i(TAG_POWER, sb.toString());
20362 sb.append("CPU for ");
20363 app.toShortString(sb);
20364 sb.append(": over ");
20365 TimeUtils.formatDuration(uptimeSince, sb);
20366 sb.append(" used ");
20367 TimeUtils.formatDuration(cputimeUsed, sb);
20369 sb.append((cputimeUsed*100)/uptimeSince);
20371 Slog.i(TAG_POWER, sb.toString());
20373 // If a process has held a wake lock for more
20374 // than 50% of the time during this period,
20375 // that sounds bad. Kill!
20376 if (doWakeKills && realtimeSince > 0
20377 && ((wtimeUsed*100)/realtimeSince) >= 50) {
20378 synchronized (stats) {
20379 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20380 realtimeSince, wtimeUsed);
20382 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20383 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20384 } else if (doCpuKills && uptimeSince > 0
20385 && ((cputimeUsed*100)/uptimeSince) >= 25) {
20386 synchronized (stats) {
20387 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20388 uptimeSince, cputimeUsed);
20390 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20391 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20393 app.lastWakeTime = wtime;
20394 app.lastCpuTime = app.curCpuTime;
20400 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20402 boolean success = true;
20404 if (app.curRawAdj != app.setRawAdj) {
20405 app.setRawAdj = app.curRawAdj;
20410 if (app.curAdj != app.setAdj) {
20411 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20412 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20413 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20415 app.setAdj = app.curAdj;
20416 app.verifiedAdj = ProcessList.INVALID_ADJ;
20419 if (app.setSchedGroup != app.curSchedGroup) {
20420 int oldSchedGroup = app.setSchedGroup;
20421 app.setSchedGroup = app.curSchedGroup;
20422 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20423 "Setting sched group of " + app.processName
20424 + " to " + app.curSchedGroup);
20425 if (app.waitingToKill != null && app.curReceiver == null
20426 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20427 app.kill(app.waitingToKill, true);
20431 switch (app.curSchedGroup) {
20432 case ProcessList.SCHED_GROUP_BACKGROUND:
20433 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20435 case ProcessList.SCHED_GROUP_TOP_APP:
20436 case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20437 processGroup = Process.THREAD_GROUP_TOP_APP;
20440 processGroup = Process.THREAD_GROUP_DEFAULT;
20443 long oldId = Binder.clearCallingIdentity();
20445 Process.setProcessGroup(app.pid, processGroup);
20446 if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20447 // do nothing if we already switched to RT
20448 if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20449 // Switch VR thread for app to SCHED_FIFO
20450 if (mInVrMode && app.vrThreadTid != 0) {
20452 Process.setThreadScheduler(app.vrThreadTid,
20453 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20454 } catch (IllegalArgumentException e) {
20455 // thread died, ignore
20458 if (mUseFifoUiScheduling) {
20459 // Switch UI pipeline for app to SCHED_FIFO
20460 app.savedPriority = Process.getThreadPriority(app.pid);
20462 Process.setThreadScheduler(app.pid,
20463 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20464 } catch (IllegalArgumentException e) {
20465 // thread died, ignore
20467 if (app.renderThreadTid != 0) {
20469 Process.setThreadScheduler(app.renderThreadTid,
20470 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20471 } catch (IllegalArgumentException e) {
20472 // thread died, ignore
20474 if (DEBUG_OOM_ADJ) {
20475 Slog.d("UI_FIFO", "Set RenderThread (TID " +
20476 app.renderThreadTid + ") to FIFO");
20479 if (DEBUG_OOM_ADJ) {
20480 Slog.d("UI_FIFO", "Not setting RenderThread TID");
20484 // Boost priority for top app UI and render threads
20485 Process.setThreadPriority(app.pid, -10);
20486 if (app.renderThreadTid != 0) {
20488 Process.setThreadPriority(app.renderThreadTid, -10);
20489 } catch (IllegalArgumentException e) {
20490 // thread died, ignore
20495 } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20496 app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20497 // Reset VR thread to SCHED_OTHER
20498 // Safe to do even if we're not in VR mode
20499 if (app.vrThreadTid != 0) {
20500 Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20502 if (mUseFifoUiScheduling) {
20503 // Reset UI pipeline to SCHED_OTHER
20504 Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20505 Process.setThreadPriority(app.pid, app.savedPriority);
20506 if (app.renderThreadTid != 0) {
20507 Process.setThreadScheduler(app.renderThreadTid,
20508 Process.SCHED_OTHER, 0);
20509 Process.setThreadPriority(app.renderThreadTid, -4);
20512 // Reset priority for top app UI and render threads
20513 Process.setThreadPriority(app.pid, 0);
20514 if (app.renderThreadTid != 0) {
20515 Process.setThreadPriority(app.renderThreadTid, 0);
20519 } catch (Exception e) {
20520 Slog.w(TAG, "Failed setting process group of " + app.pid
20521 + " to " + app.curSchedGroup);
20522 e.printStackTrace();
20524 Binder.restoreCallingIdentity(oldId);
20528 if (app.repForegroundActivities != app.foregroundActivities) {
20529 app.repForegroundActivities = app.foregroundActivities;
20530 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20532 if (app.repProcState != app.curProcState) {
20533 app.repProcState = app.curProcState;
20534 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20535 if (app.thread != null) {
20538 //RuntimeException h = new RuntimeException("here");
20539 Slog.i(TAG, "Sending new process state " + app.repProcState
20540 + " to " + app /*, h*/);
20542 app.thread.setProcessState(app.repProcState);
20543 } catch (RemoteException e) {
20547 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20548 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20549 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20550 // Experimental code to more aggressively collect pss while
20551 // running test... the problem is that this tends to collect
20552 // the data right when a process is transitioning between process
20553 // states, which well tend to give noisy data.
20554 long start = SystemClock.uptimeMillis();
20555 long pss = Debug.getPss(app.pid, mTmpLong, null);
20556 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20557 mPendingPssProcesses.remove(app);
20558 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20559 + " to " + app.curProcState + ": "
20560 + (SystemClock.uptimeMillis()-start) + "ms");
20562 app.lastStateTime = now;
20563 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20564 mTestPssMode, isSleepingLocked(), now);
20565 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20566 + ProcessList.makeProcStateString(app.setProcState) + " to "
20567 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20568 + (app.nextPssTime-now) + ": " + app);
20570 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20571 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20573 requestPssLocked(app, app.setProcState);
20574 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20575 mTestPssMode, isSleepingLocked(), now);
20576 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20577 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20579 if (app.setProcState != app.curProcState) {
20580 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20581 "Proc state change of " + app.processName
20582 + " to " + app.curProcState);
20583 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20584 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20585 if (setImportant && !curImportant) {
20586 // This app is no longer something we consider important enough to allow to
20587 // use arbitrary amounts of battery power. Note
20588 // its current wake lock time to later know to kill it if
20589 // it is not behaving well.
20590 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20591 synchronized (stats) {
20592 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20593 app.pid, nowElapsed);
20595 app.lastCpuTime = app.curCpuTime;
20598 // Inform UsageStats of important process state change
20599 // Must be called before updating setProcState
20600 maybeUpdateUsageStatsLocked(app, nowElapsed);
20602 app.setProcState = app.curProcState;
20603 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20604 app.notCachedSinceIdle = false;
20607 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20609 app.procStateChanged = true;
20611 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20612 > USAGE_STATS_INTERACTION_INTERVAL) {
20613 // For apps that sit around for a long time in the interactive state, we need
20614 // to report this at least once a day so they don't go idle.
20615 maybeUpdateUsageStatsLocked(app, nowElapsed);
20618 if (changes != 0) {
20619 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20620 "Changes in " + app + ": " + changes);
20621 int i = mPendingProcessChanges.size()-1;
20622 ProcessChangeItem item = null;
20624 item = mPendingProcessChanges.get(i);
20625 if (item.pid == app.pid) {
20626 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20627 "Re-using existing item: " + item);
20633 // No existing item in pending changes; need a new one.
20634 final int NA = mAvailProcessChanges.size();
20636 item = mAvailProcessChanges.remove(NA-1);
20637 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20638 "Retrieving available item: " + item);
20640 item = new ProcessChangeItem();
20641 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20642 "Allocating new item: " + item);
20645 item.pid = app.pid;
20646 item.uid = app.info.uid;
20647 if (mPendingProcessChanges.size() == 0) {
20648 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20649 "*** Enqueueing dispatch processes changed!");
20650 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20652 mPendingProcessChanges.add(item);
20654 item.changes |= changes;
20655 item.processState = app.repProcState;
20656 item.foregroundActivities = app.repForegroundActivities;
20657 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20658 "Item " + Integer.toHexString(System.identityHashCode(item))
20659 + " " + app.toShortString() + ": changes=" + item.changes
20660 + " procState=" + item.processState
20661 + " foreground=" + item.foregroundActivities
20662 + " type=" + app.adjType + " source=" + app.adjSource
20663 + " target=" + app.adjTarget);
20669 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20670 final UidRecord.ChangeItem pendingChange;
20671 if (uidRec == null || uidRec.pendingChange == null) {
20672 if (mPendingUidChanges.size() == 0) {
20673 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20674 "*** Enqueueing dispatch uid changed!");
20675 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20677 final int NA = mAvailUidChanges.size();
20679 pendingChange = mAvailUidChanges.remove(NA-1);
20680 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20681 "Retrieving available item: " + pendingChange);
20683 pendingChange = new UidRecord.ChangeItem();
20684 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20685 "Allocating new item: " + pendingChange);
20687 if (uidRec != null) {
20688 uidRec.pendingChange = pendingChange;
20689 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20690 // If this uid is going away, and we haven't yet reported it is gone,
20692 change = UidRecord.CHANGE_GONE_IDLE;
20694 } else if (uid < 0) {
20695 throw new IllegalArgumentException("No UidRecord or uid");
20697 pendingChange.uidRecord = uidRec;
20698 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20699 mPendingUidChanges.add(pendingChange);
20701 pendingChange = uidRec.pendingChange;
20702 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20703 change = UidRecord.CHANGE_GONE_IDLE;
20706 pendingChange.change = change;
20707 pendingChange.processState = uidRec != null
20708 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20711 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20712 String authority) {
20713 if (app == null) return;
20714 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20715 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20716 if (userState == null) return;
20717 final long now = SystemClock.elapsedRealtime();
20718 Long lastReported = userState.mProviderLastReportedFg.get(authority);
20719 if (lastReported == null || lastReported < now - 60 * 1000L) {
20720 mUsageStatsService.reportContentProviderUsage(
20721 authority, providerPkgName, app.userId);
20722 userState.mProviderLastReportedFg.put(authority, now);
20727 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20728 if (DEBUG_USAGE_STATS) {
20729 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20730 + "] state changes: old = " + app.setProcState + ", new = "
20731 + app.curProcState);
20733 if (mUsageStatsService == null) {
20736 boolean isInteraction;
20737 // To avoid some abuse patterns, we are going to be careful about what we consider
20738 // to be an app interaction. Being the top activity doesn't count while the display
20739 // is sleeping, nor do short foreground services.
20740 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20741 isInteraction = true;
20742 app.fgInteractionTime = 0;
20743 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20744 if (app.fgInteractionTime == 0) {
20745 app.fgInteractionTime = nowElapsed;
20746 isInteraction = false;
20748 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20751 isInteraction = app.curProcState
20752 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20753 app.fgInteractionTime = 0;
20755 if (isInteraction && (!app.reportedInteraction
20756 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20757 app.interactionEventTime = nowElapsed;
20758 String[] packages = app.getPackageList();
20759 if (packages != null) {
20760 for (int i = 0; i < packages.length; i++) {
20761 mUsageStatsService.reportEvent(packages[i], app.userId,
20762 UsageEvents.Event.SYSTEM_INTERACTION);
20766 app.reportedInteraction = isInteraction;
20767 if (!isInteraction) {
20768 app.interactionEventTime = 0;
20772 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20773 if (proc.thread != null) {
20774 if (proc.baseProcessTracker != null) {
20775 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20780 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20781 ProcessRecord TOP_APP, boolean doingAll, long now) {
20782 if (app.thread == null) {
20786 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20788 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20791 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20793 if (isForeground != proc.foregroundServices) {
20794 proc.foregroundServices = isForeground;
20795 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20797 if (isForeground) {
20798 if (curProcs == null) {
20799 curProcs = new ArrayList<ProcessRecord>();
20800 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20802 if (!curProcs.contains(proc)) {
20803 curProcs.add(proc);
20804 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20805 proc.info.packageName, proc.info.uid);
20808 if (curProcs != null) {
20809 if (curProcs.remove(proc)) {
20810 mBatteryStatsService.noteEvent(
20811 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20812 proc.info.packageName, proc.info.uid);
20813 if (curProcs.size() <= 0) {
20814 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20820 updateOomAdjLocked();
20825 private final ActivityRecord resumedAppLocked() {
20826 ActivityRecord act = mStackSupervisor.resumedAppLocked();
20830 pkg = act.packageName;
20831 uid = act.info.applicationInfo.uid;
20836 // Has the UID or resumed package name changed?
20837 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20838 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20839 if (mCurResumedPackage != null) {
20840 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20841 mCurResumedPackage, mCurResumedUid);
20843 mCurResumedPackage = pkg;
20844 mCurResumedUid = uid;
20845 if (mCurResumedPackage != null) {
20846 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20847 mCurResumedPackage, mCurResumedUid);
20853 final boolean updateOomAdjLocked(ProcessRecord app) {
20854 final ActivityRecord TOP_ACT = resumedAppLocked();
20855 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20856 final boolean wasCached = app.cached;
20860 // This is the desired cached adjusment we want to tell it to use.
20861 // If our app is currently cached, we know it, and that is it. Otherwise,
20862 // we don't know it yet, and it needs to now be cached we will then
20863 // need to do a complete oom adj.
20864 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20865 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20866 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20867 SystemClock.uptimeMillis());
20868 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20869 // Changed to/from cached state, so apps after it in the LRU
20870 // list may also be changed.
20871 updateOomAdjLocked();
20876 final void updateOomAdjLocked() {
20877 final ActivityRecord TOP_ACT = resumedAppLocked();
20878 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20879 final long now = SystemClock.uptimeMillis();
20880 final long nowElapsed = SystemClock.elapsedRealtime();
20881 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20882 final int N = mLruProcesses.size();
20885 RuntimeException e = new RuntimeException();
20886 e.fillInStackTrace();
20887 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20890 // Reset state in all uid records.
20891 for (int i=mActiveUids.size()-1; i>=0; i--) {
20892 final UidRecord uidRec = mActiveUids.valueAt(i);
20893 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20894 "Starting update of " + uidRec);
20898 mStackSupervisor.rankTaskLayersIfNeeded();
20901 mNewNumServiceProcs = 0;
20902 mNewNumAServiceProcs = 0;
20904 final int emptyProcessLimit;
20905 final int cachedProcessLimit;
20906 if (mProcessLimit <= 0) {
20907 emptyProcessLimit = cachedProcessLimit = 0;
20908 } else if (mProcessLimit == 1) {
20909 emptyProcessLimit = 1;
20910 cachedProcessLimit = 0;
20912 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20913 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20916 // Let's determine how many processes we have running vs.
20917 // how many slots we have for background processes; we may want
20918 // to put multiple processes in a slot of there are enough of
20920 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20921 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20922 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20923 if (numEmptyProcs > cachedProcessLimit) {
20924 // If there are more empty processes than our limit on cached
20925 // processes, then use the cached process limit for the factor.
20926 // This ensures that the really old empty processes get pushed
20927 // down to the bottom, so if we are running low on memory we will
20928 // have a better chance at keeping around more cached processes
20929 // instead of a gazillion empty processes.
20930 numEmptyProcs = cachedProcessLimit;
20932 int emptyFactor = numEmptyProcs/numSlots;
20933 if (emptyFactor < 1) emptyFactor = 1;
20934 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20935 if (cachedFactor < 1) cachedFactor = 1;
20936 int stepCached = 0;
20940 int numTrimming = 0;
20942 mNumNonCachedProcs = 0;
20943 mNumCachedHiddenProcs = 0;
20945 // First update the OOM adjustment for each of the
20946 // application processes based on their current state.
20947 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20948 int nextCachedAdj = curCachedAdj+1;
20949 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20950 int nextEmptyAdj = curEmptyAdj+2;
20951 for (int i=N-1; i>=0; i--) {
20952 ProcessRecord app = mLruProcesses.get(i);
20953 if (!app.killedByAm && app.thread != null) {
20954 app.procStateChanged = false;
20955 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20957 // If we haven't yet assigned the final cached adj
20958 // to the process, do that now.
20959 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20960 switch (app.curProcState) {
20961 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20962 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20963 // This process is a cached process holding activities...
20964 // assign it the next cached value for that type, and then
20965 // step that cached level.
20966 app.curRawAdj = curCachedAdj;
20967 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20968 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20969 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20971 if (curCachedAdj != nextCachedAdj) {
20973 if (stepCached >= cachedFactor) {
20975 curCachedAdj = nextCachedAdj;
20976 nextCachedAdj += 2;
20977 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20978 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20984 // For everything else, assign next empty cached process
20985 // level and bump that up. Note that this means that
20986 // long-running services that have dropped down to the
20987 // cached level will be treated as empty (since their process
20988 // state is still as a service), which is what we want.
20989 app.curRawAdj = curEmptyAdj;
20990 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20991 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20992 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20994 if (curEmptyAdj != nextEmptyAdj) {
20996 if (stepEmpty >= emptyFactor) {
20998 curEmptyAdj = nextEmptyAdj;
21000 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21001 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21009 applyOomAdjLocked(app, true, now, nowElapsed);
21011 // Count the number of process types.
21012 switch (app.curProcState) {
21013 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21014 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21015 mNumCachedHiddenProcs++;
21017 if (numCached > cachedProcessLimit) {
21018 app.kill("cached #" + numCached, true);
21021 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21022 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21023 && app.lastActivityTime < oldTime) {
21024 app.kill("empty for "
21025 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21026 / 1000) + "s", true);
21029 if (numEmpty > emptyProcessLimit) {
21030 app.kill("empty #" + numEmpty, true);
21035 mNumNonCachedProcs++;
21039 if (app.isolated && app.services.size() <= 0) {
21040 // If this is an isolated process, and there are no
21041 // services running in it, then the process is no longer
21042 // needed. We agressively kill these because we can by
21043 // definition not re-use the same process again, and it is
21044 // good to avoid having whatever code was running in them
21045 // left sitting around after no longer needed.
21046 app.kill("isolated not needed", true);
21048 // Keeping this process, update its uid.
21049 final UidRecord uidRec = app.uidRecord;
21050 if (uidRec != null && uidRec.curProcState > app.curProcState) {
21051 uidRec.curProcState = app.curProcState;
21055 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21056 && !app.killedByAm) {
21062 mNumServiceProcs = mNewNumServiceProcs;
21064 // Now determine the memory trimming level of background processes.
21065 // Unfortunately we need to start at the back of the list to do this
21066 // properly. We only do this if the number of background apps we
21067 // are managing to keep around is less than half the maximum we desire;
21068 // if we are keeping a good number around, we'll let them use whatever
21069 // memory they want.
21070 final int numCachedAndEmpty = numCached + numEmpty;
21072 if (numCached <= ProcessList.TRIM_CACHED_APPS
21073 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21074 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21075 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21076 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21077 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21079 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21082 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21084 // We always allow the memory level to go up (better). We only allow it to go
21085 // down if we are in a state where that is allowed, *and* the total number of processes
21086 // has gone down since last time.
21087 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21088 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21089 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21090 if (memFactor > mLastMemoryLevel) {
21091 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21092 memFactor = mLastMemoryLevel;
21093 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21096 if (memFactor != mLastMemoryLevel) {
21097 EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21099 mLastMemoryLevel = memFactor;
21100 mLastNumProcesses = mLruProcesses.size();
21101 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21102 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21103 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21104 if (mLowRamStartTime == 0) {
21105 mLowRamStartTime = now;
21109 switch (memFactor) {
21110 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21111 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21113 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21114 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21117 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21120 int factor = numTrimming/3;
21122 if (mHomeProcess != null) minFactor++;
21123 if (mPreviousProcess != null) minFactor++;
21124 if (factor < minFactor) factor = minFactor;
21125 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21126 for (int i=N-1; i>=0; i--) {
21127 ProcessRecord app = mLruProcesses.get(i);
21128 if (allChanged || app.procStateChanged) {
21129 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21130 app.procStateChanged = false;
21132 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21133 && !app.killedByAm) {
21134 if (app.trimMemoryLevel < curLevel && app.thread != null) {
21136 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21137 "Trimming memory of " + app.processName + " to " + curLevel);
21138 app.thread.scheduleTrimMemory(curLevel);
21139 } catch (RemoteException e) {
21142 // For now we won't do this; our memory trimming seems
21143 // to be good enough at this point that destroying
21144 // activities causes more harm than good.
21145 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21146 && app != mHomeProcess && app != mPreviousProcess) {
21147 // Need to do this on its own message because the stack may not
21148 // be in a consistent state at this point.
21149 // For these apps we will also finish their activities
21150 // to help them free memory.
21151 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21155 app.trimMemoryLevel = curLevel;
21157 if (step >= factor) {
21159 switch (curLevel) {
21160 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21161 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21163 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21164 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21168 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21169 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21170 && app.thread != null) {
21172 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21173 "Trimming memory of heavy-weight " + app.processName
21174 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21175 app.thread.scheduleTrimMemory(
21176 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21177 } catch (RemoteException e) {
21180 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21182 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21183 || app.systemNoUi) && app.pendingUiClean) {
21184 // If this application is now in the background and it
21185 // had done UI, then give it the special trim level to
21186 // have it free UI resources.
21187 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21188 if (app.trimMemoryLevel < level && app.thread != null) {
21190 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21191 "Trimming memory of bg-ui " + app.processName
21193 app.thread.scheduleTrimMemory(level);
21194 } catch (RemoteException e) {
21197 app.pendingUiClean = false;
21199 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21201 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21202 "Trimming memory of fg " + app.processName
21203 + " to " + fgTrimLevel);
21204 app.thread.scheduleTrimMemory(fgTrimLevel);
21205 } catch (RemoteException e) {
21208 app.trimMemoryLevel = fgTrimLevel;
21212 if (mLowRamStartTime != 0) {
21213 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21214 mLowRamStartTime = 0;
21216 for (int i=N-1; i>=0; i--) {
21217 ProcessRecord app = mLruProcesses.get(i);
21218 if (allChanged || app.procStateChanged) {
21219 setProcessTrackerStateLocked(app, trackerMemFactor, now);
21220 app.procStateChanged = false;
21222 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21223 || app.systemNoUi) && app.pendingUiClean) {
21224 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21225 && app.thread != null) {
21227 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21228 "Trimming memory of ui hidden " + app.processName
21229 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21230 app.thread.scheduleTrimMemory(
21231 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21232 } catch (RemoteException e) {
21235 app.pendingUiClean = false;
21237 app.trimMemoryLevel = 0;
21241 if (mAlwaysFinishActivities) {
21242 // Need to do this on its own message because the stack may not
21243 // be in a consistent state at this point.
21244 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21248 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21251 // Update from any uid changes.
21252 for (int i=mActiveUids.size()-1; i>=0; i--) {
21253 final UidRecord uidRec = mActiveUids.valueAt(i);
21254 int uidChange = UidRecord.CHANGE_PROCSTATE;
21255 if (uidRec.setProcState != uidRec.curProcState) {
21256 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21257 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21258 + " to " + uidRec.curProcState);
21259 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21260 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21261 uidRec.lastBackgroundTime = nowElapsed;
21262 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21263 // Note: the background settle time is in elapsed realtime, while
21264 // the handler time base is uptime. All this means is that we may
21265 // stop background uids later than we had intended, but that only
21266 // happens because the device was sleeping so we are okay anyway.
21267 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21272 uidChange = UidRecord.CHANGE_ACTIVE;
21273 uidRec.idle = false;
21275 uidRec.lastBackgroundTime = 0;
21277 uidRec.setProcState = uidRec.curProcState;
21278 enqueueUidChangeLocked(uidRec, -1, uidChange);
21279 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21283 if (mProcessStats.shouldWriteNowLocked(now)) {
21284 mHandler.post(new Runnable() {
21285 @Override public void run() {
21286 synchronized (ActivityManagerService.this) {
21287 mProcessStats.writeStateAsyncLocked();
21293 if (DEBUG_OOM_ADJ) {
21294 final long duration = SystemClock.uptimeMillis() - now;
21296 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21297 new RuntimeException("here").fillInStackTrace());
21299 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21304 final void idleUids() {
21305 synchronized (this) {
21306 final long nowElapsed = SystemClock.elapsedRealtime();
21307 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21309 for (int i=mActiveUids.size()-1; i>=0; i--) {
21310 final UidRecord uidRec = mActiveUids.valueAt(i);
21311 final long bgTime = uidRec.lastBackgroundTime;
21312 if (bgTime > 0 && !uidRec.idle) {
21313 if (bgTime <= maxBgTime) {
21314 uidRec.idle = true;
21315 doStopUidLocked(uidRec.uid, uidRec);
21317 if (nextTime == 0 || nextTime > bgTime) {
21323 if (nextTime > 0) {
21324 mHandler.removeMessages(IDLE_UIDS_MSG);
21325 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21326 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21331 final void runInBackgroundDisabled(int uid) {
21332 synchronized (this) {
21333 UidRecord uidRec = mActiveUids.get(uid);
21334 if (uidRec != null) {
21335 // This uid is actually running... should it be considered background now?
21337 doStopUidLocked(uidRec.uid, uidRec);
21340 // This uid isn't actually running... still send a report about it being "stopped".
21341 doStopUidLocked(uid, null);
21346 final void doStopUidLocked(int uid, final UidRecord uidRec) {
21347 mServices.stopInBackgroundLocked(uid);
21348 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21351 final void trimApplications() {
21352 synchronized (this) {
21355 // First remove any unused application processes whose package
21356 // has been removed.
21357 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21358 final ProcessRecord app = mRemovedProcesses.get(i);
21359 if (app.activities.size() == 0
21360 && app.curReceiver == null && app.services.size() == 0) {
21362 TAG, "Exiting empty application process "
21363 + app.toShortString() + " ("
21364 + (app.thread != null ? app.thread.asBinder() : null)
21366 if (app.pid > 0 && app.pid != MY_PID) {
21367 app.kill("empty", false);
21370 app.thread.scheduleExit();
21371 } catch (Exception e) {
21372 // Ignore exceptions.
21375 cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21376 mRemovedProcesses.remove(i);
21378 if (app.persistent) {
21379 addAppLocked(app.info, false, null /* ABI override */);
21384 // Now update the oom adj for all processes.
21385 updateOomAdjLocked();
21389 /** This method sends the specified signal to each of the persistent apps */
21390 public void signalPersistentProcesses(int sig) throws RemoteException {
21391 if (sig != Process.SIGNAL_USR1) {
21392 throw new SecurityException("Only SIGNAL_USR1 is allowed");
21395 synchronized (this) {
21396 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21397 != PackageManager.PERMISSION_GRANTED) {
21398 throw new SecurityException("Requires permission "
21399 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21402 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21403 ProcessRecord r = mLruProcesses.get(i);
21404 if (r.thread != null && r.persistent) {
21405 Process.sendSignal(r.pid, sig);
21411 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21412 if (proc == null || proc == mProfileProc) {
21413 proc = mProfileProc;
21414 profileType = mProfileType;
21415 clearProfilerLocked();
21417 if (proc == null) {
21421 proc.thread.profilerControl(false, null, profileType);
21422 } catch (RemoteException e) {
21423 throw new IllegalStateException("Process disappeared");
21427 private void clearProfilerLocked() {
21428 if (mProfileFd != null) {
21430 mProfileFd.close();
21431 } catch (IOException e) {
21434 mProfileApp = null;
21435 mProfileProc = null;
21436 mProfileFile = null;
21438 mAutoStopProfiler = false;
21439 mSamplingInterval = 0;
21442 public boolean profileControl(String process, int userId, boolean start,
21443 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21446 synchronized (this) {
21447 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21448 // its own permission.
21449 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21450 != PackageManager.PERMISSION_GRANTED) {
21451 throw new SecurityException("Requires permission "
21452 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21455 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21456 throw new IllegalArgumentException("null profile info or fd");
21459 ProcessRecord proc = null;
21460 if (process != null) {
21461 proc = findProcessLocked(process, userId, "profileControl");
21464 if (start && (proc == null || proc.thread == null)) {
21465 throw new IllegalArgumentException("Unknown process: " + process);
21469 stopProfilerLocked(null, 0);
21470 setProfileApp(proc.info, proc.processName, profilerInfo);
21471 mProfileProc = proc;
21472 mProfileType = profileType;
21473 ParcelFileDescriptor fd = profilerInfo.profileFd;
21476 } catch (IOException e) {
21479 profilerInfo.profileFd = fd;
21480 proc.thread.profilerControl(start, profilerInfo, profileType);
21484 stopProfilerLocked(proc, profileType);
21485 if (profilerInfo != null && profilerInfo.profileFd != null) {
21487 profilerInfo.profileFd.close();
21488 } catch (IOException e) {
21495 } catch (RemoteException e) {
21496 throw new IllegalStateException("Process disappeared");
21498 if (profilerInfo != null && profilerInfo.profileFd != null) {
21500 profilerInfo.profileFd.close();
21501 } catch (IOException e) {
21507 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21508 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21509 userId, true, ALLOW_FULL_ONLY, callName, null);
21510 ProcessRecord proc = null;
21512 int pid = Integer.parseInt(process);
21513 synchronized (mPidsSelfLocked) {
21514 proc = mPidsSelfLocked.get(pid);
21516 } catch (NumberFormatException e) {
21519 if (proc == null) {
21520 ArrayMap<String, SparseArray<ProcessRecord>> all
21521 = mProcessNames.getMap();
21522 SparseArray<ProcessRecord> procs = all.get(process);
21523 if (procs != null && procs.size() > 0) {
21524 proc = procs.valueAt(0);
21525 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21526 for (int i=1; i<procs.size(); i++) {
21527 ProcessRecord thisProc = procs.valueAt(i);
21528 if (thisProc.userId == userId) {
21540 public boolean dumpHeap(String process, int userId, boolean managed,
21541 String path, ParcelFileDescriptor fd) throws RemoteException {
21544 synchronized (this) {
21545 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21546 // its own permission (same as profileControl).
21547 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21548 != PackageManager.PERMISSION_GRANTED) {
21549 throw new SecurityException("Requires permission "
21550 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21554 throw new IllegalArgumentException("null fd");
21557 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21558 if (proc == null || proc.thread == null) {
21559 throw new IllegalArgumentException("Unknown process: " + process);
21562 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21563 if (!isDebuggable) {
21564 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21565 throw new SecurityException("Process not debuggable: " + proc);
21569 proc.thread.dumpHeap(managed, path, fd);
21573 } catch (RemoteException e) {
21574 throw new IllegalStateException("Process disappeared");
21579 } catch (IOException e) {
21586 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21587 String reportPackage) {
21588 if (processName != null) {
21589 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21590 "setDumpHeapDebugLimit()");
21592 synchronized (mPidsSelfLocked) {
21593 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21594 if (proc == null) {
21595 throw new SecurityException("No process found for calling pid "
21596 + Binder.getCallingPid());
21598 if (!Build.IS_DEBUGGABLE
21599 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21600 throw new SecurityException("Not running a debuggable build");
21602 processName = proc.processName;
21604 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21605 throw new SecurityException("Package " + reportPackage + " is not running in "
21610 synchronized (this) {
21611 if (maxMemSize > 0) {
21612 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21615 mMemWatchProcesses.remove(processName, uid);
21617 mMemWatchProcesses.getMap().remove(processName);
21624 public void dumpHeapFinished(String path) {
21625 synchronized (this) {
21626 if (Binder.getCallingPid() != mMemWatchDumpPid) {
21627 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21628 + " does not match last pid " + mMemWatchDumpPid);
21631 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21632 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21633 + " does not match last path " + mMemWatchDumpFile);
21636 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21637 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21641 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21642 public void monitor() {
21643 synchronized (this) { }
21646 void onCoreSettingsChange(Bundle settings) {
21647 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21648 ProcessRecord processRecord = mLruProcesses.get(i);
21650 if (processRecord.thread != null) {
21651 processRecord.thread.setCoreSettings(settings);
21653 } catch (RemoteException re) {
21659 // Multi-user methods
21662 * Start user, if its not already running, but don't bring it to foreground.
21665 public boolean startUserInBackground(final int userId) {
21666 return mUserController.startUser(userId, /* foreground */ false);
21670 public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21671 return mUserController.unlockUser(userId, token, secret, listener);
21675 public boolean switchUser(final int targetUserId) {
21676 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21677 UserInfo currentUserInfo;
21678 UserInfo targetUserInfo;
21679 synchronized (this) {
21680 int currentUserId = mUserController.getCurrentUserIdLocked();
21681 currentUserInfo = mUserController.getUserInfo(currentUserId);
21682 targetUserInfo = mUserController.getUserInfo(targetUserId);
21683 if (targetUserInfo == null) {
21684 Slog.w(TAG, "No user info for user #" + targetUserId);
21687 if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21688 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21689 + " when device is in demo mode");
21692 if (!targetUserInfo.supportsSwitchTo()) {
21693 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21696 if (targetUserInfo.isManagedProfile()) {
21697 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21700 mUserController.setTargetUserIdLocked(targetUserId);
21702 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21703 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21704 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21708 void scheduleStartProfilesLocked() {
21709 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21710 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21711 DateUtils.SECOND_IN_MILLIS);
21716 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21717 return mUserController.stopUser(userId, force, callback);
21721 public UserInfo getCurrentUser() {
21722 return mUserController.getCurrentUser();
21726 public boolean isUserRunning(int userId, int flags) {
21727 if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21728 && checkCallingPermission(INTERACT_ACROSS_USERS)
21729 != PackageManager.PERMISSION_GRANTED) {
21730 String msg = "Permission Denial: isUserRunning() from pid="
21731 + Binder.getCallingPid()
21732 + ", uid=" + Binder.getCallingUid()
21733 + " requires " + INTERACT_ACROSS_USERS;
21735 throw new SecurityException(msg);
21737 synchronized (this) {
21738 return mUserController.isUserRunningLocked(userId, flags);
21743 public int[] getRunningUserIds() {
21744 if (checkCallingPermission(INTERACT_ACROSS_USERS)
21745 != PackageManager.PERMISSION_GRANTED) {
21746 String msg = "Permission Denial: isUserRunning() from pid="
21747 + Binder.getCallingPid()
21748 + ", uid=" + Binder.getCallingUid()
21749 + " requires " + INTERACT_ACROSS_USERS;
21751 throw new SecurityException(msg);
21753 synchronized (this) {
21754 return mUserController.getStartedUserArrayLocked();
21759 public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21760 mUserController.registerUserSwitchObserver(observer, name);
21764 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21765 mUserController.unregisterUserSwitchObserver(observer);
21768 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21769 if (info == null) return null;
21770 ApplicationInfo newInfo = new ApplicationInfo(info);
21771 newInfo.initForUser(userId);
21775 public boolean isUserStopped(int userId) {
21776 synchronized (this) {
21777 return mUserController.getStartedUserStateLocked(userId) == null;
21781 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21783 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21787 ActivityInfo info = new ActivityInfo(aInfo);
21788 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21792 private boolean processSanityChecksLocked(ProcessRecord process) {
21793 if (process == null || process.thread == null) {
21797 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21798 if (!isDebuggable) {
21799 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21807 public boolean startBinderTracking() throws RemoteException {
21808 synchronized (this) {
21809 mBinderTransactionTrackingEnabled = true;
21810 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21811 // permission (same as profileControl).
21812 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21813 != PackageManager.PERMISSION_GRANTED) {
21814 throw new SecurityException("Requires permission "
21815 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21818 for (int i = 0; i < mLruProcesses.size(); i++) {
21819 ProcessRecord process = mLruProcesses.get(i);
21820 if (!processSanityChecksLocked(process)) {
21824 process.thread.startBinderTracking();
21825 } catch (RemoteException e) {
21826 Log.v(TAG, "Process disappared");
21833 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21835 synchronized (this) {
21836 mBinderTransactionTrackingEnabled = false;
21837 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21838 // permission (same as profileControl).
21839 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21840 != PackageManager.PERMISSION_GRANTED) {
21841 throw new SecurityException("Requires permission "
21842 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21846 throw new IllegalArgumentException("null fd");
21849 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21850 pw.println("Binder transaction traces for all processes.\n");
21851 for (ProcessRecord process : mLruProcesses) {
21852 if (!processSanityChecksLocked(process)) {
21856 pw.println("Traces for process: " + process.processName);
21859 TransferPipe tp = new TransferPipe();
21861 process.thread.stopBinderTrackingAndDump(
21862 tp.getWriteFd().getFileDescriptor());
21863 tp.go(fd.getFileDescriptor());
21867 } catch (IOException e) {
21868 pw.println("Failure while dumping IPC traces from " + process +
21869 ". Exception: " + e);
21871 } catch (RemoteException e) {
21872 pw.println("Got a RemoteException while dumping IPC traces from " +
21873 process + ". Exception: " + e);
21884 } catch (IOException e) {
21890 private final class LocalService extends ActivityManagerInternal {
21892 public String checkContentProviderAccess(String authority, int userId) {
21893 return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21897 public void onWakefulnessChanged(int wakefulness) {
21898 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21902 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21903 String processName, String abiOverride, int uid, Runnable crashHandler) {
21904 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21905 processName, abiOverride, uid, crashHandler);
21909 public SleepToken acquireSleepToken(String tag) {
21910 Preconditions.checkNotNull(tag);
21912 ComponentName requestedVrService = null;
21913 ComponentName callingVrActivity = null;
21915 synchronized (ActivityManagerService.this) {
21916 if (mFocusedActivity != null) {
21917 requestedVrService = mFocusedActivity.requestedVrComponent;
21918 callingVrActivity = mFocusedActivity.info.getComponentName();
21919 userId = mFocusedActivity.userId;
21923 if (requestedVrService != null) {
21924 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21927 synchronized (ActivityManagerService.this) {
21928 SleepTokenImpl token = new SleepTokenImpl(tag);
21929 mSleepTokens.add(token);
21930 updateSleepIfNeededLocked();
21936 public ComponentName getHomeActivityForUser(int userId) {
21937 synchronized (ActivityManagerService.this) {
21938 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21939 return homeActivity == null ? null : homeActivity.realActivity;
21944 public void onUserRemoved(int userId) {
21945 synchronized (ActivityManagerService.this) {
21946 ActivityManagerService.this.onUserStoppedLocked(userId);
21951 public void onLocalVoiceInteractionStarted(IBinder activity,
21952 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21953 synchronized (ActivityManagerService.this) {
21954 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21955 voiceSession, voiceInteractor);
21960 public void notifyStartingWindowDrawn() {
21961 synchronized (ActivityManagerService.this) {
21962 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21967 public void notifyAppTransitionStarting(int reason) {
21968 synchronized (ActivityManagerService.this) {
21969 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21974 public void notifyAppTransitionFinished() {
21975 synchronized (ActivityManagerService.this) {
21976 mStackSupervisor.notifyAppTransitionDone();
21981 public void notifyAppTransitionCancelled() {
21982 synchronized (ActivityManagerService.this) {
21983 mStackSupervisor.notifyAppTransitionDone();
21988 public List<IBinder> getTopVisibleActivities() {
21989 synchronized (ActivityManagerService.this) {
21990 return mStackSupervisor.getTopVisibleActivities();
21995 public void notifyDockedStackMinimizedChanged(boolean minimized) {
21996 synchronized (ActivityManagerService.this) {
21997 mStackSupervisor.setDockedStackMinimized(minimized);
22002 public void killForegroundAppsForUser(int userHandle) {
22003 synchronized (ActivityManagerService.this) {
22004 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22005 final int NP = mProcessNames.getMap().size();
22006 for (int ip = 0; ip < NP; ip++) {
22007 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22008 final int NA = apps.size();
22009 for (int ia = 0; ia < NA; ia++) {
22010 final ProcessRecord app = apps.valueAt(ia);
22011 if (app.persistent) {
22012 // We don't kill persistent processes.
22017 } else if (app.userId == userHandle && app.foregroundActivities) {
22018 app.removed = true;
22024 final int N = procs.size();
22025 for (int i = 0; i < N; i++) {
22026 removeProcessLocked(procs.get(i), false, true, "kill all fg");
22032 public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22033 if (!(target instanceof PendingIntentRecord)) {
22034 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22037 ((PendingIntentRecord) target).setWhitelistDuration(duration);
22041 public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22043 Preconditions.checkNotNull(values, "Configuration must not be null");
22044 Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22045 synchronized (ActivityManagerService.this) {
22046 updateConfigurationLocked(values, null, false, true, userId,
22047 false /* deferResume */);
22052 public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22054 Preconditions.checkNotNull(intents, "intents");
22055 final String[] resolvedTypes = new String[intents.length];
22056 for (int i = 0; i < intents.length; i++) {
22057 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22060 // UID of the package on user userId.
22061 // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22062 // packageUid may not be initialized.
22063 int packageUid = 0;
22065 packageUid = AppGlobals.getPackageManager().getPackageUid(
22066 packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22067 } catch (RemoteException e) {
22068 // Shouldn't happen.
22071 synchronized (ActivityManagerService.this) {
22072 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22073 /*resultTo*/ null, bOptions, userId);
22078 public int getUidProcessState(int uid) {
22079 return getUidState(uid);
22083 private final class SleepTokenImpl extends SleepToken {
22084 private final String mTag;
22085 private final long mAcquireTime;
22087 public SleepTokenImpl(String tag) {
22089 mAcquireTime = SystemClock.uptimeMillis();
22093 public void release() {
22094 synchronized (ActivityManagerService.this) {
22095 if (mSleepTokens.remove(this)) {
22096 updateSleepIfNeededLocked();
22102 public String toString() {
22103 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22108 * An implementation of IAppTask, that allows an app to manage its own tasks via
22109 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
22110 * only the process that calls getAppTasks() can call the AppTask methods.
22112 class AppTaskImpl extends IAppTask.Stub {
22113 private int mTaskId;
22114 private int mCallingUid;
22116 public AppTaskImpl(int taskId, int callingUid) {
22118 mCallingUid = callingUid;
22121 private void checkCaller() {
22122 if (mCallingUid != Binder.getCallingUid()) {
22123 throw new SecurityException("Caller " + mCallingUid
22124 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22129 public void finishAndRemoveTask() {
22132 synchronized (ActivityManagerService.this) {
22133 long origId = Binder.clearCallingIdentity();
22135 // We remove the task from recents to preserve backwards
22136 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22137 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22140 Binder.restoreCallingIdentity(origId);
22146 public ActivityManager.RecentTaskInfo getTaskInfo() {
22149 synchronized (ActivityManagerService.this) {
22150 long origId = Binder.clearCallingIdentity();
22152 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22154 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22156 return createRecentTaskInfoFromTaskRecord(tr);
22158 Binder.restoreCallingIdentity(origId);
22164 public void moveToFront() {
22166 // Will bring task to front if it already has a root activity.
22167 final long origId = Binder.clearCallingIdentity();
22169 synchronized (this) {
22170 mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22173 Binder.restoreCallingIdentity(origId);
22178 public int startActivity(IBinder whoThread, String callingPackage,
22179 Intent intent, String resolvedType, Bundle bOptions) {
22182 int callingUser = UserHandle.getCallingUserId();
22184 IApplicationThread appThread;
22185 synchronized (ActivityManagerService.this) {
22186 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22188 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22190 appThread = ApplicationThreadNative.asInterface(whoThread);
22191 if (appThread == null) {
22192 throw new IllegalArgumentException("Bad app thread " + appThread);
22195 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22196 resolvedType, null, null, null, null, 0, 0, null, null,
22197 null, bOptions, false, callingUser, null, tr);
22201 public void setExcludeFromRecents(boolean exclude) {
22204 synchronized (ActivityManagerService.this) {
22205 long origId = Binder.clearCallingIdentity();
22207 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22209 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22211 Intent intent = tr.getBaseIntent();
22213 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22215 intent.setFlags(intent.getFlags()
22216 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22219 Binder.restoreCallingIdentity(origId);
22226 * Kill processes for the user with id userId and that depend on the package named packageName
22229 public void killPackageDependents(String packageName, int userId) {
22230 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22231 if (packageName == null) {
22232 throw new NullPointerException(
22233 "Cannot kill the dependents of a package without its name.");
22236 long callingId = Binder.clearCallingIdentity();
22237 IPackageManager pm = AppGlobals.getPackageManager();
22240 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22241 } catch (RemoteException e) {
22243 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22244 throw new IllegalArgumentException(
22245 "Cannot kill dependents of non-existing package " + packageName);
22248 synchronized(this) {
22249 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22250 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22251 "dep: " + packageName);
22254 Binder.restoreCallingIdentity(callingId);