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.google.android.collect.Lists;
20 import com.google.android.collect.Maps;
21 import com.android.internal.R;
22 import com.android.internal.annotations.GuardedBy;
23 import com.android.internal.app.AssistUtils;
24 import com.android.internal.app.DumpHeapActivity;
25 import com.android.internal.app.IAppOpsCallback;
26 import com.android.internal.app.IAppOpsService;
27 import com.android.internal.app.IVoiceInteractor;
28 import com.android.internal.app.ProcessMap;
29 import com.android.internal.app.ProcessStats;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.os.BackgroundThread;
32 import com.android.internal.os.BatteryStatsImpl;
33 import com.android.internal.os.IResultReceiver;
34 import com.android.internal.os.ProcessCpuTracker;
35 import com.android.internal.os.TransferPipe;
36 import com.android.internal.os.Zygote;
37 import com.android.internal.os.InstallerConnection.InstallerException;
38 import com.android.internal.util.ArrayUtils;
39 import com.android.internal.util.FastPrintWriter;
40 import com.android.internal.util.FastXmlSerializer;
41 import com.android.internal.util.MemInfoReader;
42 import com.android.internal.util.Preconditions;
43 import com.android.server.AppOpsService;
44 import com.android.server.AttributeCache;
45 import com.android.server.DeviceIdleController;
46 import com.android.server.IntentResolver;
47 import com.android.server.LocalServices;
48 import com.android.server.LockGuard;
49 import com.android.server.ServiceThread;
50 import com.android.server.SystemService;
51 import com.android.server.SystemServiceManager;
52 import com.android.server.Watchdog;
53 import com.android.server.am.ActivityStack.ActivityState;
54 import com.android.server.firewall.IntentFirewall;
55 import com.android.server.pm.Installer;
56 import com.android.server.statusbar.StatusBarManagerInternal;
57 import com.android.server.vr.VrManagerInternal;
58 import com.android.server.wm.AppTransition;
59 import com.android.server.wm.WindowManagerService;
61 import org.xmlpull.v1.XmlPullParser;
62 import org.xmlpull.v1.XmlPullParserException;
63 import org.xmlpull.v1.XmlSerializer;
65 import android.Manifest;
66 import android.annotation.UserIdInt;
67 import android.app.Activity;
68 import android.app.ActivityManager;
69 import android.app.ActivityManager.RunningTaskInfo;
70 import android.app.ActivityManager.StackId;
71 import android.app.ActivityManager.StackInfo;
72 import android.app.ActivityManager.TaskThumbnailInfo;
73 import android.app.ActivityManagerInternal;
74 import android.app.ActivityManagerInternal.SleepToken;
75 import android.app.ActivityManagerNative;
76 import android.app.ActivityOptions;
77 import android.app.ActivityThread;
78 import android.app.AlertDialog;
79 import android.app.AppGlobals;
80 import android.app.AppOpsManager;
81 import android.app.ApplicationErrorReport;
82 import android.app.ApplicationThreadNative;
83 import android.app.BroadcastOptions;
84 import android.app.Dialog;
85 import android.app.IActivityContainer;
86 import android.app.IActivityContainerCallback;
87 import android.app.IActivityController;
88 import android.app.IAppTask;
89 import android.app.IApplicationThread;
90 import android.app.IInstrumentationWatcher;
91 import android.app.INotificationManager;
92 import android.app.IProcessObserver;
93 import android.app.IServiceConnection;
94 import android.app.IStopUserCallback;
95 import android.app.ITaskStackListener;
96 import android.app.IUiAutomationConnection;
97 import android.app.IUidObserver;
98 import android.app.IUserSwitchObserver;
99 import android.app.Instrumentation;
100 import android.app.Notification;
101 import android.app.NotificationManager;
102 import android.app.PendingIntent;
103 import android.app.ProfilerInfo;
104 import android.app.admin.DevicePolicyManager;
105 import android.app.admin.DevicePolicyManagerInternal;
106 import android.app.admin.IDevicePolicyManager;
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.Looper;
171 import android.os.Message;
172 import android.os.Parcel;
173 import android.os.ParcelFileDescriptor;
174 import android.os.PersistableBundle;
175 import android.os.PowerManager;
176 import android.os.PowerManagerInternal;
177 import android.os.Process;
178 import android.os.RemoteCallbackList;
179 import android.os.RemoteException;
180 import android.os.ResultReceiver;
181 import android.os.ServiceManager;
182 import android.os.StrictMode;
183 import android.os.SystemClock;
184 import android.os.SystemProperties;
185 import android.os.Trace;
186 import android.os.TransactionTooLargeException;
187 import android.os.UpdateLock;
188 import android.os.UserHandle;
189 import android.os.UserManager;
190 import android.os.WorkSource;
191 import android.os.storage.IMountService;
192 import android.os.storage.MountServiceInternal;
193 import android.os.storage.StorageManager;
194 import android.provider.Settings;
195 import android.service.voice.IVoiceInteractionSession;
196 import android.service.voice.VoiceInteractionManagerInternal;
197 import android.service.voice.VoiceInteractionSession;
198 import android.text.format.DateUtils;
199 import android.text.format.Time;
200 import android.util.ArrayMap;
201 import android.util.ArraySet;
202 import android.util.AtomicFile;
203 import android.util.DebugUtils;
204 import android.util.EventLog;
205 import android.util.LocaleList;
206 import android.util.Log;
207 import android.util.Pair;
208 import android.util.PrintWriterPrinter;
209 import android.util.Slog;
210 import android.util.SparseArray;
211 import android.util.TimeUtils;
212 import android.util.Xml;
213 import android.view.Display;
214 import android.view.Gravity;
215 import android.view.LayoutInflater;
216 import android.view.View;
217 import android.view.WindowManager;
219 import java.io.BufferedInputStream;
220 import java.io.BufferedOutputStream;
221 import java.io.DataInputStream;
222 import java.io.DataOutputStream;
224 import java.io.FileDescriptor;
225 import java.io.FileInputStream;
226 import java.io.FileNotFoundException;
227 import java.io.FileOutputStream;
228 import java.io.IOException;
229 import java.io.InputStreamReader;
230 import java.io.PrintWriter;
231 import java.io.StringWriter;
232 import java.lang.ref.WeakReference;
233 import java.nio.charset.StandardCharsets;
234 import java.util.ArrayList;
235 import java.util.Arrays;
236 import java.util.Collections;
237 import java.util.Comparator;
238 import java.util.HashMap;
239 import java.util.HashSet;
240 import java.util.Iterator;
241 import java.util.List;
242 import java.util.Locale;
243 import java.util.Map;
244 import java.util.Set;
245 import java.util.concurrent.atomic.AtomicBoolean;
246 import java.util.concurrent.atomic.AtomicLong;
248 import dalvik.system.VMRuntime;
250 import libcore.io.IoUtils;
251 import libcore.util.EmptyArray;
253 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
254 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
255 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
256 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
257 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
258 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
259 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
260 import static android.app.ActivityManager.StackId.FIRST_STATIC_STACK_ID;
261 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265 import static android.app.ActivityManager.StackId.LAST_STATIC_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_PICTURE_IN_PICTURE;
269 import static android.content.pm.PackageManager.GET_PROVIDERS;
270 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
272 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
273 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
274 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
275 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
276 import static android.provider.Settings.Global.DEBUG_APP;
277 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
278 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
279 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
280 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
281 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
282 import static android.provider.Settings.System.FONT_SCALE;
283 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
284 import static com.android.internal.util.XmlUtils.readIntAttribute;
285 import static com.android.internal.util.XmlUtils.readLongAttribute;
286 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
287 import static com.android.internal.util.XmlUtils.writeIntAttribute;
288 import static com.android.internal.util.XmlUtils.writeLongAttribute;
289 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
290 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
291 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
292 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
293 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
294 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
321 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
322 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
323 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
324 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
325 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
326 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
327 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
345 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
346 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
347 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
348 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
349 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
350 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
351 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
352 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
353 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
354 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
355 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
356 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
357 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
358 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
359 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
360 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
361 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
362 import static org.xmlpull.v1.XmlPullParser.START_TAG;
364 public final class ActivityManagerService extends ActivityManagerNative
365 implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
367 // File that stores last updated system version and called preboot receivers
368 static final String CALLED_PRE_BOOTS_FILENAME = "called_pre_boots.dat";
370 private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
371 private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
372 private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
373 private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
374 private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
375 private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
376 private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
377 private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
378 private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
379 private static final String TAG_LRU = TAG + POSTFIX_LRU;
380 private static final String TAG_MU = TAG + POSTFIX_MU;
381 private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
382 private static final String TAG_POWER = TAG + POSTFIX_POWER;
383 private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
384 private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
385 private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
386 private static final String TAG_PSS = TAG + POSTFIX_PSS;
387 private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
388 private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
389 private static final String TAG_STACK = TAG + POSTFIX_STACK;
390 private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
391 private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
392 private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
393 private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
394 private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
396 /** Control over CPU and battery monitoring */
397 // write battery stats every 30 minutes.
398 static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
399 static final boolean MONITOR_CPU_USAGE = true;
400 // don't sample cpu less than every 5 seconds.
401 static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
402 // wait possibly forever for next cpu sample.
403 static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
404 static final boolean MONITOR_THREAD_CPU_USAGE = false;
406 // The flags that are set for all calls we make to the package manager.
407 static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
409 static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
411 static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
413 // Amount of time after a call to stopAppSwitches() during which we will
414 // prevent further untrusted switches from happening.
415 static final long APP_SWITCH_DELAY_TIME = 5*1000;
417 // How long we wait for a launched process to attach to the activity manager
418 // before we decide it's never going to come up for real.
419 static final int PROC_START_TIMEOUT = 10*1000;
420 // How long we wait for an attached process to publish its content providers
421 // before we decide it must be hung.
422 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
424 // How long we will retain processes hosting content providers in the "last activity"
425 // state before allowing them to drop down to the regular cached LRU list. This is
426 // to avoid thrashing of provider processes under low memory situations.
427 static final int CONTENT_PROVIDER_RETAIN_TIME = 20*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, when the process was
431 // started with a wrapper for instrumentation (such as Valgrind) because it
432 // could take much longer than usual.
433 static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
435 // How long to wait after going idle before forcing apps to GC.
436 static final int GC_TIMEOUT = 5*1000;
438 // The minimum amount of time between successive GC requests for a process.
439 static final int GC_MIN_INTERVAL = 60*1000;
441 // The minimum amount of time between successive PSS requests for a process.
442 static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
444 // The minimum amount of time between successive PSS requests for a process
445 // when the request is due to the memory state being lowered.
446 static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
448 // The rate at which we check for apps using excessive power -- 15 mins.
449 static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
451 // The minimum sample duration we will allow before deciding we have
452 // enough data on wake locks to start killing things.
453 static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
455 // The minimum sample duration we will allow before deciding we have
456 // enough data on CPU usage to start killing things.
457 static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
459 // How long we allow a receiver to run before giving up on it.
460 static final int BROADCAST_FG_TIMEOUT = 10*1000;
461 static final int BROADCAST_BG_TIMEOUT = 60*1000;
463 // How long we wait until we timeout on key dispatching.
464 static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
466 // How long we wait until we timeout on key dispatching during instrumentation.
467 static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
469 // This is the amount of time an app needs to be running a foreground service before
470 // we will consider it to be doing interaction for usage stats.
471 static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
473 // Maximum amount of time we will allow to elapse before re-reporting usage stats
474 // interaction with foreground processes.
475 static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
477 // This is the amount of time we allow an app to settle after it goes into the background,
478 // before we start restricting what it can do.
479 static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
481 // How long to wait in getAssistContextExtras for the activity and foreground services
482 // to respond with the result.
483 static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
485 // How long top wait when going through the modern assist (which doesn't need to block
486 // on getting this result before starting to launch its UI).
487 static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
489 // Maximum number of persisted Uri grants a package is allowed
490 static final int MAX_PERSISTED_URI_GRANTS = 128;
492 static final int MY_PID = Process.myPid();
494 static final String[] EMPTY_STRING_ARRAY = new String[0];
496 // How many bytes to write into the dropbox log before truncating
497 static final int DROPBOX_MAX_SIZE = 256 * 1024;
499 // Access modes for handleIncomingUser.
500 static final int ALLOW_NON_FULL = 0;
501 static final int ALLOW_NON_FULL_IN_PROFILE = 1;
502 static final int ALLOW_FULL_ONLY = 2;
504 static final int LAST_PREBOOT_DELIVERED_FILE_VERSION = 10000;
506 // Delay in notifying task stack change listeners (in millis)
507 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
509 // Necessary ApplicationInfo flags to mark an app as persistent
510 private static final int PERSISTENT_MASK =
511 ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
513 // Intent sent when remote bugreport collection has been completed
514 private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
515 "android.intent.action.REMOTE_BUGREPORT_FINISHED";
517 // Delay to disable app launch boost
518 static final int APP_BOOST_MESSAGE_DELAY = 3000;
519 // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
520 static final int APP_BOOST_TIMEOUT = 2500;
522 // Used to indicate that a task is removed it should also be removed from recents.
523 private static final boolean REMOVE_FROM_RECENTS = true;
524 // Used to indicate that an app transition should be animated.
525 static final boolean ANIMATE = true;
527 // Determines whether to take full screen screenshots
528 static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
530 private static native int nativeMigrateToBoost();
531 private static native int nativeMigrateFromBoost();
532 private boolean mIsBoosted = false;
533 private long mBoostStartTime = 0;
535 /** All system services */
536 SystemServiceManager mSystemServiceManager;
538 private Installer mInstaller;
540 /** Run all ActivityStacks through this */
541 final ActivityStackSupervisor mStackSupervisor;
543 final ActivityStarter mActivityStarter;
545 /** Task stack change listeners. */
546 private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
547 new RemoteCallbackList<ITaskStackListener>();
549 final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
551 public IntentFirewall mIntentFirewall;
553 // Whether we should show our dialogs (ANR, crash, etc) or just perform their
554 // default actuion automatically. Important for devices without direct input
556 private boolean mShowDialogs = true;
557 private boolean mInVrMode = false;
559 BroadcastQueue mFgBroadcastQueue;
560 BroadcastQueue mBgBroadcastQueue;
561 // Convenient for easy iteration over the queues. Foreground is first
562 // so that dispatch of foreground broadcasts gets precedence.
563 final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
565 BroadcastQueue broadcastQueueForIntent(Intent intent) {
566 final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
567 if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
568 "Broadcast intent " + intent + " on "
569 + (isFg ? "foreground" : "background") + " queue");
570 return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
574 * Activity we have told the window manager to have key focus.
576 ActivityRecord mFocusedActivity = null;
579 * User id of the last activity mFocusedActivity was set to.
581 private int mLastFocusedUserId;
584 * If non-null, we are tracking the time the user spends in the currently focused app.
586 private AppTimeTracker mCurAppTimeTracker;
589 * List of intents that were used to start the most recent tasks.
591 final RecentTasks mRecentTasks;
594 * For addAppTask: cached of the last activity component that was added.
596 ComponentName mLastAddedTaskComponent;
599 * For addAppTask: cached of the last activity uid that was added.
601 int mLastAddedTaskUid;
604 * For addAppTask: cached of the last ActivityInfo that was added.
606 ActivityInfo mLastAddedTaskActivity;
609 * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
611 SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
614 * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
616 String mDeviceOwnerName;
618 final UserController mUserController;
620 final AppErrors mAppErrors;
622 boolean mDoingSetFocusedActivity;
624 public boolean canShowErrorDialogs() {
625 return mShowDialogs && !mSleeping && !mShuttingDown;
628 public class PendingAssistExtras extends Binder implements Runnable {
629 public final ActivityRecord activity;
630 public final Bundle extras;
631 public final Intent intent;
632 public final String hint;
633 public final IResultReceiver receiver;
634 public final int userHandle;
635 public boolean haveResult = false;
636 public Bundle result = null;
637 public AssistStructure structure = null;
638 public AssistContent content = null;
639 public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
640 String _hint, IResultReceiver _receiver, int _userHandle) {
641 activity = _activity;
645 receiver = _receiver;
646 userHandle = _userHandle;
650 Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
651 synchronized (this) {
655 pendingAssistExtrasTimedOut(this);
659 final ArrayList<PendingAssistExtras> mPendingAssistExtras
660 = new ArrayList<PendingAssistExtras>();
663 * Process management.
665 final ProcessList mProcessList = new ProcessList();
668 * All of the applications we currently have running organized by name.
669 * The keys are strings of the application package name (as
670 * returned by the package manager), and the keys are ApplicationRecord
673 final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
676 * Tracking long-term execution of processes to look for abuse and other
679 final ProcessStatsService mProcessStats;
682 * The currently running isolated processes.
684 final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
687 * Counter for assigning isolated process uids, to avoid frequently reusing the
690 int mNextIsolatedProcessUid = 0;
693 * The currently running heavy-weight process, if any.
695 ProcessRecord mHeavyWeightProcess = null;
698 * All of the processes we currently have running organized by pid.
699 * The keys are the pid running the application.
701 * <p>NOTE: This object is protected by its own lock, NOT the global
702 * activity manager lock!
704 final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
707 * All of the processes that have been forced to be foreground. The key
708 * is the pid of the caller who requested it (we hold a death
711 abstract class ForegroundToken implements IBinder.DeathRecipient {
715 final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
718 * List of records for processes that someone had tried to start before the
719 * system was ready. We don't start them at that point, but ensure they
720 * are started by the time booting is complete.
722 final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
725 * List of persistent applications that are in the process
728 final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
731 * Processes that are being forcibly torn down.
733 final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
736 * List of running applications, sorted by recent usage.
737 * The first entry in the list is the least recently used.
739 final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
742 * Where in mLruProcesses that the processes hosting activities start.
744 int mLruProcessActivityStart = 0;
747 * Where in mLruProcesses that the processes hosting services start.
748 * This is after (lower index) than mLruProcessesActivityStart.
750 int mLruProcessServiceStart = 0;
753 * List of processes that should gc as soon as things are idle.
755 final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
758 * Processes we want to collect PSS data from.
760 final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
762 private boolean mBinderTransactionTrackingEnabled = false;
765 * Last time we requested PSS data of all processes.
767 long mLastFullPssTime = SystemClock.uptimeMillis();
770 * If set, the next time we collect PSS data we should do a full collection
771 * with data from native processes and the kernel.
773 boolean mFullPssPending = false;
776 * This is the process holding what we currently consider to be
777 * the "home" activity.
779 ProcessRecord mHomeProcess;
782 * This is the process holding the activity the user last visited that
783 * is in a different process from the one they are currently in.
785 ProcessRecord mPreviousProcess;
788 * The time at which the previous process was last visible.
790 long mPreviousProcessVisibleTime;
793 * Track all uids that have actively running processes.
795 final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
798 * This is for verifying the UID report flow.
800 static final boolean VALIDATE_UID_STATES = true;
801 final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
804 * Packages that the user has asked to have run in screen size
805 * compatibility mode instead of filling the screen.
807 final CompatModePackages mCompatModePackages;
810 * Set of IntentSenderRecord objects that are currently active.
812 final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
813 = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
816 * Fingerprints (hashCode()) of stack traces that we've
817 * already logged DropBox entries for. Guarded by itself. If
818 * something (rogue user app) forces this over
819 * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
821 private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
822 private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
825 * Strict Mode background batched logging state.
827 * The string buffer is guarded by itself, and its lock is also
828 * used to determine if another batched write is already
831 private final StringBuilder mStrictModeBuffer = new StringBuilder();
834 * Keeps track of all IIntentReceivers that have been registered for broadcasts.
835 * Hash keys are the receiver IBinder, hash value is a ReceiverList.
837 final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
840 * Resolver for broadcast intents to registered receivers.
841 * Holds BroadcastFilter (subclass of IntentFilter).
843 final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
844 = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
846 protected boolean allowFilterResult(
847 BroadcastFilter filter, List<BroadcastFilter> dest) {
848 IBinder target = filter.receiverList.receiver.asBinder();
849 for (int i = dest.size() - 1; i >= 0; i--) {
850 if (dest.get(i).receiverList.receiver.asBinder() == target) {
858 protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
859 if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
860 || userId == filter.owningUserId) {
861 return super.newResult(filter, match, userId);
867 protected BroadcastFilter[] newArray(int size) {
868 return new BroadcastFilter[size];
872 protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
873 return packageName.equals(filter.packageName);
878 * State of all active sticky broadcasts per user. Keys are the action of the
879 * sticky Intent, values are an ArrayList of all broadcasted intents with
880 * that action (which should usually be one). The SparseArray is keyed
881 * by the user ID the sticky is for, and can include UserHandle.USER_ALL
882 * for stickies that are sent to all users.
884 final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
885 new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
887 final ActiveServices mServices;
889 final static class Association {
890 final int mSourceUid;
891 final String mSourceProcess;
892 final int mTargetUid;
893 final ComponentName mTargetComponent;
894 final String mTargetProcess;
902 Association(int sourceUid, String sourceProcess, int targetUid,
903 ComponentName targetComponent, String targetProcess) {
904 mSourceUid = sourceUid;
905 mSourceProcess = sourceProcess;
906 mTargetUid = targetUid;
907 mTargetComponent = targetComponent;
908 mTargetProcess = targetProcess;
913 * When service association tracking is enabled, this is all of the associations we
914 * have seen. Mapping is target uid -> target component -> source uid -> source process name
915 * -> association data.
917 final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
918 mAssociations = new SparseArray<>();
919 boolean mTrackingAssociations;
922 * Backup/restore process management
924 String mBackupAppName = null;
925 BackupRecord mBackupTarget = null;
927 final ProviderMap mProviderMap;
930 * List of content providers who have clients waiting for them. The
931 * application is currently being launched and the provider will be
932 * removed from this list once it is published.
934 final ArrayList<ContentProviderRecord> mLaunchingProviders
935 = new ArrayList<ContentProviderRecord>();
938 * File storing persisted {@link #mGrantedUriPermissions}.
940 private final AtomicFile mGrantFile;
942 /** XML constants used in {@link #mGrantFile} */
943 private static final String TAG_URI_GRANTS = "uri-grants";
944 private static final String TAG_URI_GRANT = "uri-grant";
945 private static final String ATTR_USER_HANDLE = "userHandle";
946 private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
947 private static final String ATTR_TARGET_USER_ID = "targetUserId";
948 private static final String ATTR_SOURCE_PKG = "sourcePkg";
949 private static final String ATTR_TARGET_PKG = "targetPkg";
950 private static final String ATTR_URI = "uri";
951 private static final String ATTR_MODE_FLAGS = "modeFlags";
952 private static final String ATTR_CREATED_TIME = "createdTime";
953 private static final String ATTR_PREFIX = "prefix";
956 * Global set of specific {@link Uri} permissions that have been granted.
957 * This optimized lookup structure maps from {@link UriPermission#targetUid}
958 * to {@link UriPermission#uri} to {@link UriPermission}.
961 private final SparseArray<ArrayMap<GrantUri, UriPermission>>
962 mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
964 public static class GrantUri {
965 public final int sourceUserId;
966 public final Uri uri;
967 public boolean prefix;
969 public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
970 this.sourceUserId = sourceUserId;
972 this.prefix = prefix;
976 public int hashCode() {
978 hashCode = 31 * hashCode + sourceUserId;
979 hashCode = 31 * hashCode + uri.hashCode();
980 hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
985 public boolean equals(Object o) {
986 if (o instanceof GrantUri) {
987 GrantUri other = (GrantUri) o;
988 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
989 && prefix == other.prefix;
995 public String toString() {
996 String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
997 if (prefix) result += " [prefix]";
1001 public String toSafeString() {
1002 String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1003 if (prefix) result += " [prefix]";
1007 public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1008 return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1009 ContentProvider.getUriWithoutUserId(uri), false);
1013 CoreSettingsObserver mCoreSettingsObserver;
1015 FontScaleSettingObserver mFontScaleSettingObserver;
1017 private final class FontScaleSettingObserver extends ContentObserver {
1018 private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1020 public FontScaleSettingObserver() {
1022 ContentResolver resolver = mContext.getContentResolver();
1023 resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1027 public void onChange(boolean selfChange, Uri uri) {
1028 if (mFontScaleUri.equals(uri)) {
1029 updateFontScaleIfNeeded();
1035 * Thread-local storage used to carry caller permissions over through
1036 * indirect content-provider access.
1038 private class Identity {
1039 public final IBinder token;
1040 public final int pid;
1041 public final int uid;
1043 Identity(IBinder _token, int _pid, int _uid) {
1050 private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1053 * All information we have collected about the runtime performance of
1054 * any user id that can impact battery performance.
1056 final BatteryStatsService mBatteryStatsService;
1059 * Information about component usage
1061 UsageStatsManagerInternal mUsageStatsService;
1064 * Access to DeviceIdleController service.
1066 DeviceIdleController.LocalService mLocalDeviceIdleController;
1069 * Information about and control over application operations
1071 final AppOpsService mAppOpsService;
1074 * Current configuration information. HistoryRecord objects are given
1075 * a reference to this object to indicate which configuration they are
1076 * currently running in, so this object must be kept immutable.
1078 Configuration mConfiguration = new Configuration();
1081 * Current sequencing integer of the configuration, for skipping old
1084 int mConfigurationSeq = 0;
1086 boolean mSuppressResizeConfigChanges = false;
1089 * Hardware-reported OpenGLES version.
1091 final int GL_ES_VERSION;
1094 * List of initialization arguments to pass to all processes when binding applications to them.
1095 * For example, references to the commonly used services.
1097 HashMap<String, IBinder> mAppBindArgs;
1100 * Temporary to avoid allocations. Protected by main lock.
1102 final StringBuilder mStringBuilder = new StringBuilder(256);
1105 * Used to control how we initialize the service.
1107 ComponentName mTopComponent;
1108 String mTopAction = Intent.ACTION_MAIN;
1110 boolean mProcessesReady = false;
1111 boolean mSystemReady = false;
1112 boolean mBooting = false;
1113 boolean mCallFinishBooting = false;
1114 boolean mBootAnimationComplete = false;
1115 boolean mWaitingUpdate = false;
1116 boolean mDidUpdate = false;
1117 boolean mOnBattery = false;
1118 boolean mLaunchWarningShown = false;
1124 boolean mCheckedForSetup;
1127 * The time at which we will allow normal application switches again,
1128 * after a call to {@link #stopAppSwitches()}.
1130 long mAppSwitchesAllowedTime;
1133 * This is set to true after the first switch after mAppSwitchesAllowedTime
1134 * is set; any switches after that will clear the time.
1136 boolean mDidAppSwitch;
1139 * Last time (in realtime) at which we checked for power usage.
1141 long mLastPowerCheckRealtime;
1144 * Last time (in uptime) at which we checked for power usage.
1146 long mLastPowerCheckUptime;
1149 * Set while we are wanting to sleep, to prevent any
1150 * activities from being started/resumed.
1152 private boolean mSleeping = false;
1155 * The process state used for processes that are running the top activities.
1156 * This changes between TOP and TOP_SLEEPING to following mSleeping.
1158 int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1161 * Set while we are running a voice interaction. This overrides
1162 * sleeping while it is active.
1164 private IVoiceInteractionSession mRunningVoice;
1167 * For some direct access we need to power manager.
1169 PowerManagerInternal mLocalPowerManager;
1172 * We want to hold a wake lock while running a voice interaction session, since
1173 * this may happen with the screen off and we need to keep the CPU running to
1174 * be able to continue to interact with the user.
1176 PowerManager.WakeLock mVoiceWakeLock;
1179 * State of external calls telling us if the device is awake or asleep.
1181 private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1184 * A list of tokens that cause the top activity to be put to sleep.
1185 * They are used by components that may hide and block interaction with underlying
1188 final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1190 static final int LOCK_SCREEN_HIDDEN = 0;
1191 static final int LOCK_SCREEN_LEAVING = 1;
1192 static final int LOCK_SCREEN_SHOWN = 2;
1194 * State of external call telling us if the lock screen is shown.
1196 int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1199 * Set if we are shutting down the system, similar to sleeping.
1201 boolean mShuttingDown = false;
1204 * Current sequence id for oom_adj computation traversal.
1209 * Current sequence id for process LRU updating.
1214 * Keep track of the non-cached/empty process we last found, to help
1215 * determine how to distribute cached/empty processes next time.
1217 int mNumNonCachedProcs = 0;
1220 * Keep track of the number of cached hidden procs, to balance oom adj
1221 * distribution between those and empty procs.
1223 int mNumCachedHiddenProcs = 0;
1226 * Keep track of the number of service processes we last found, to
1227 * determine on the next iteration which should be B services.
1229 int mNumServiceProcs = 0;
1230 int mNewNumAServiceProcs = 0;
1231 int mNewNumServiceProcs = 0;
1234 * Allow the current computed overall memory level of the system to go down?
1235 * This is set to false when we are killing processes for reasons other than
1236 * memory management, so that the now smaller process list will not be taken as
1237 * an indication that memory is tighter.
1239 boolean mAllowLowerMemLevel = false;
1242 * The last computed memory level, for holding when we are in a state that
1243 * processes are going away for other reasons.
1245 int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1248 * The last total number of process we have, to determine if changes actually look
1249 * like a shrinking number of process due to lower RAM.
1251 int mLastNumProcesses;
1254 * The uptime of the last time we performed idle maintenance.
1256 long mLastIdleTime = SystemClock.uptimeMillis();
1259 * Total time spent with RAM that has been added in the past since the last idle time.
1261 long mLowRamTimeSinceLastIdle = 0;
1264 * If RAM is currently low, when that horrible situation started.
1266 long mLowRamStartTime = 0;
1269 * For reporting to battery stats the current top application.
1271 private String mCurResumedPackage = null;
1272 private int mCurResumedUid = -1;
1275 * For reporting to battery stats the apps currently running foreground
1276 * service. The ProcessMap is package/uid tuples; each of these contain
1277 * an array of the currently foreground processes.
1279 final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1280 = new ProcessMap<ArrayList<ProcessRecord>>();
1283 * This is set if we had to do a delayed dexopt of an app before launching
1284 * it, to increase the ANR timeouts in that case.
1289 * Set if the systemServer made a call to enterSafeMode.
1294 * If true, we are running under a test environment so will sample PSS from processes
1295 * much more rapidly to try to collect better data when the tests are rapidly
1296 * running through apps.
1298 boolean mTestPssMode = false;
1300 String mDebugApp = null;
1301 boolean mWaitForDebugger = false;
1302 boolean mDebugTransient = false;
1303 String mOrigDebugApp = null;
1304 boolean mOrigWaitForDebugger = false;
1305 boolean mAlwaysFinishActivities = false;
1306 boolean mLenientBackgroundCheck = false;
1307 boolean mForceResizableActivities;
1308 boolean mSupportsMultiWindow;
1309 boolean mSupportsFreeformWindowManagement;
1310 boolean mSupportsPictureInPicture;
1311 Rect mDefaultPinnedStackBounds;
1312 IActivityController mController = null;
1313 boolean mControllerIsAMonkey = false;
1314 String mProfileApp = null;
1315 ProcessRecord mProfileProc = null;
1316 String mProfileFile;
1317 ParcelFileDescriptor mProfileFd;
1318 int mSamplingInterval = 0;
1319 boolean mAutoStopProfiler = false;
1320 int mProfileType = 0;
1321 final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1322 String mMemWatchDumpProcName;
1323 String mMemWatchDumpFile;
1324 int mMemWatchDumpPid;
1325 int mMemWatchDumpUid;
1326 String mTrackAllocationApp = null;
1327 String mNativeDebuggingApp = null;
1329 final long[] mTmpLong = new long[2];
1331 static final class ProcessChangeItem {
1332 static final int CHANGE_ACTIVITIES = 1<<0;
1333 static final int CHANGE_PROCESS_STATE = 1<<1;
1338 boolean foregroundActivities;
1341 final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1342 ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1344 final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1345 final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1347 final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1348 UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1350 final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1351 final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1354 * Runtime CPU use collection thread. This object's lock is used to
1355 * perform synchronization with the thread (notifying it to run).
1357 final Thread mProcessCpuThread;
1360 * Used to collect per-process CPU use for ANRs, battery stats, etc.
1361 * Must acquire this object's lock when accessing it.
1362 * NOTE: this lock will be held while doing long operations (trawling
1363 * through all processes in /proc), so it should never be acquired by
1364 * any critical paths such as when holding the main activity manager lock.
1366 final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1367 MONITOR_THREAD_CPU_USAGE);
1368 final AtomicLong mLastCpuTime = new AtomicLong(0);
1369 final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1371 long mLastWriteTime = 0;
1374 * Used to retain an update lock when the foreground activity is in
1377 final UpdateLock mUpdateLock = new UpdateLock("immersive");
1380 * Set to true after the system has finished booting.
1382 boolean mBooted = false;
1384 int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1385 int mProcessLimitOverride = -1;
1387 WindowManagerService mWindowManager;
1388 final ActivityThread mSystemThread;
1390 private final class AppDeathRecipient implements IBinder.DeathRecipient {
1391 final ProcessRecord mApp;
1393 final IApplicationThread mAppThread;
1395 AppDeathRecipient(ProcessRecord app, int pid,
1396 IApplicationThread thread) {
1397 if (DEBUG_ALL) Slog.v(
1398 TAG, "New death recipient " + this
1399 + " for thread " + thread.asBinder());
1402 mAppThread = thread;
1406 public void binderDied() {
1407 if (DEBUG_ALL) Slog.v(
1408 TAG, "Death received in " + this
1409 + " for thread " + mAppThread.asBinder());
1410 synchronized(ActivityManagerService.this) {
1411 appDiedLocked(mApp, mPid, mAppThread, true);
1416 static final int SHOW_ERROR_UI_MSG = 1;
1417 static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1418 static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1419 static final int UPDATE_CONFIGURATION_MSG = 4;
1420 static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1421 static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1422 static final int SERVICE_TIMEOUT_MSG = 12;
1423 static final int UPDATE_TIME_ZONE = 13;
1424 static final int SHOW_UID_ERROR_UI_MSG = 14;
1425 static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1426 static final int PROC_START_TIMEOUT_MSG = 20;
1427 static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1428 static final int KILL_APPLICATION_MSG = 22;
1429 static final int FINALIZE_PENDING_INTENT_MSG = 23;
1430 static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1431 static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1432 static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1433 static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1434 static final int CLEAR_DNS_CACHE_MSG = 28;
1435 static final int UPDATE_HTTP_PROXY_MSG = 29;
1436 static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1437 static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1438 static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1439 static final int REPORT_MEM_USAGE_MSG = 33;
1440 static final int REPORT_USER_SWITCH_MSG = 34;
1441 static final int CONTINUE_USER_SWITCH_MSG = 35;
1442 static final int USER_SWITCH_TIMEOUT_MSG = 36;
1443 static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1444 static final int PERSIST_URI_GRANTS_MSG = 38;
1445 static final int REQUEST_ALL_PSS_MSG = 39;
1446 static final int START_PROFILES_MSG = 40;
1447 static final int UPDATE_TIME = 41;
1448 static final int SYSTEM_USER_START_MSG = 42;
1449 static final int SYSTEM_USER_CURRENT_MSG = 43;
1450 static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1451 static final int FINISH_BOOTING_MSG = 45;
1452 static final int START_USER_SWITCH_UI_MSG = 46;
1453 static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1454 static final int DISMISS_DIALOG_UI_MSG = 48;
1455 static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1456 static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1457 static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1458 static final int DELETE_DUMPHEAP_MSG = 52;
1459 static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1460 static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1461 static final int REPORT_TIME_TRACKER_MSG = 55;
1462 static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1463 static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1464 static final int APP_BOOST_DEACTIVATE_MSG = 58;
1465 static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1466 static final int IDLE_UIDS_MSG = 60;
1467 static final int SYSTEM_USER_UNLOCK_MSG = 61;
1468 static final int LOG_STACK_STATE = 62;
1469 static final int VR_MODE_CHANGE_MSG = 63;
1470 static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1471 static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1472 static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1474 static final int FIRST_ACTIVITY_STACK_MSG = 100;
1475 static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1476 static final int FIRST_COMPAT_MODE_MSG = 300;
1477 static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1479 CompatModeDialog mCompatModeDialog;
1480 long mLastMemUsageReportTime = 0;
1483 * Flag whether the current user is a "monkey", i.e. whether
1484 * the UI is driven by a UI automation tool.
1486 private boolean mUserIsMonkey;
1488 /** Flag whether the device has a Recents UI */
1489 boolean mHasRecents;
1491 /** The dimensions of the thumbnails in the Recents UI. */
1492 int mThumbnailWidth;
1493 int mThumbnailHeight;
1495 final ServiceThread mHandlerThread;
1496 final MainHandler mHandler;
1497 final UiHandler mUiHandler;
1498 final ProcessStartLogger mProcessStartLogger;
1500 PackageManagerInternal mPackageManagerInt;
1502 final class UiHandler extends Handler {
1503 public UiHandler() {
1504 super(com.android.server.UiThread.get().getLooper(), null, true);
1508 public void handleMessage(Message msg) {
1510 case SHOW_ERROR_UI_MSG: {
1511 mAppErrors.handleShowAppErrorUi(msg);
1512 ensureBootCompleted();
1514 case SHOW_NOT_RESPONDING_UI_MSG: {
1515 mAppErrors.handleShowAnrUi(msg);
1516 ensureBootCompleted();
1518 case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1519 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1520 synchronized (ActivityManagerService.this) {
1521 ProcessRecord proc = (ProcessRecord) data.get("app");
1523 Slog.e(TAG, "App not found when showing strict mode dialog.");
1526 if (proc.crashDialog != null) {
1527 Slog.e(TAG, "App already has strict mode dialog: " + proc);
1530 AppErrorResult res = (AppErrorResult) data.get("result");
1531 if (mShowDialogs && !mSleeping && !mShuttingDown) {
1532 Dialog d = new StrictModeViolationDialog(mContext,
1533 ActivityManagerService.this, res, proc);
1535 proc.crashDialog = d;
1537 // The device is asleep, so just pretend that the user
1538 // saw a crash dialog and hit "force quit".
1542 ensureBootCompleted();
1544 case SHOW_FACTORY_ERROR_UI_MSG: {
1545 Dialog d = new FactoryErrorDialog(
1546 mContext, msg.getData().getCharSequence("msg"));
1548 ensureBootCompleted();
1550 case WAIT_FOR_DEBUGGER_UI_MSG: {
1551 synchronized (ActivityManagerService.this) {
1552 ProcessRecord app = (ProcessRecord)msg.obj;
1553 if (msg.arg1 != 0) {
1554 if (!app.waitedForDebugger) {
1555 Dialog d = new AppWaitingForDebuggerDialog(
1556 ActivityManagerService.this,
1559 app.waitedForDebugger = true;
1563 if (app.waitDialog != null) {
1564 app.waitDialog.dismiss();
1565 app.waitDialog = null;
1570 case SHOW_UID_ERROR_UI_MSG: {
1572 AlertDialog d = new BaseErrorDialog(mContext);
1573 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1574 d.setCancelable(false);
1575 d.setTitle(mContext.getText(R.string.android_system_label));
1576 d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1577 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1578 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1582 case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1584 AlertDialog d = new BaseErrorDialog(mContext);
1585 d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1586 d.setCancelable(false);
1587 d.setTitle(mContext.getText(R.string.android_system_label));
1588 d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1589 d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1590 obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1594 case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1595 synchronized (ActivityManagerService.this) {
1596 ActivityRecord ar = (ActivityRecord) msg.obj;
1597 if (mCompatModeDialog != null) {
1598 if (mCompatModeDialog.mAppInfo.packageName.equals(
1599 ar.info.applicationInfo.packageName)) {
1602 mCompatModeDialog.dismiss();
1603 mCompatModeDialog = null;
1605 if (ar != null && false) {
1606 if (mCompatModePackages.getPackageAskCompatModeLocked(
1608 int mode = mCompatModePackages.computeCompatModeLocked(
1609 ar.info.applicationInfo);
1610 if (mode == ActivityManager.COMPAT_MODE_DISABLED
1611 || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1612 mCompatModeDialog = new CompatModeDialog(
1613 ActivityManagerService.this, mContext,
1614 ar.info.applicationInfo);
1615 mCompatModeDialog.show();
1622 case START_USER_SWITCH_UI_MSG: {
1623 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1626 case DISMISS_DIALOG_UI_MSG: {
1627 final Dialog d = (Dialog) msg.obj;
1631 case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1632 dispatchProcessesChanged();
1635 case DISPATCH_PROCESS_DIED_UI_MSG: {
1636 final int pid = msg.arg1;
1637 final int uid = msg.arg2;
1638 dispatchProcessDied(pid, uid);
1641 case DISPATCH_UIDS_CHANGED_UI_MSG: {
1642 dispatchUidsChanged();
1648 final class MainHandler extends Handler {
1649 public MainHandler(Looper looper) {
1650 super(looper, null, true);
1654 public void handleMessage(Message msg) {
1656 case UPDATE_CONFIGURATION_MSG: {
1657 final ContentResolver resolver = mContext.getContentResolver();
1658 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1661 case GC_BACKGROUND_PROCESSES_MSG: {
1662 synchronized (ActivityManagerService.this) {
1663 performAppGcsIfAppropriateLocked();
1666 case SERVICE_TIMEOUT_MSG: {
1669 Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1671 mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1674 mServices.serviceTimeout((ProcessRecord)msg.obj);
1676 case UPDATE_TIME_ZONE: {
1677 synchronized (ActivityManagerService.this) {
1678 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1679 ProcessRecord r = mLruProcesses.get(i);
1680 if (r.thread != null) {
1682 r.thread.updateTimeZone();
1683 } catch (RemoteException ex) {
1684 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1690 case CLEAR_DNS_CACHE_MSG: {
1691 synchronized (ActivityManagerService.this) {
1692 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1693 ProcessRecord r = mLruProcesses.get(i);
1694 if (r.thread != null) {
1696 r.thread.clearDnsCache();
1697 } catch (RemoteException ex) {
1698 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1704 case UPDATE_HTTP_PROXY_MSG: {
1705 ProxyInfo proxy = (ProxyInfo)msg.obj;
1708 String exclList = "";
1709 Uri pacFileUrl = Uri.EMPTY;
1710 if (proxy != null) {
1711 host = proxy.getHost();
1712 port = Integer.toString(proxy.getPort());
1713 exclList = proxy.getExclusionListAsString();
1714 pacFileUrl = proxy.getPacFileUrl();
1716 synchronized (ActivityManagerService.this) {
1717 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1718 ProcessRecord r = mLruProcesses.get(i);
1719 if (r.thread != null) {
1721 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1722 } catch (RemoteException ex) {
1723 Slog.w(TAG, "Failed to update http proxy for: " +
1724 r.info.processName);
1730 case PROC_START_TIMEOUT_MSG: {
1733 Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1735 mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1738 ProcessRecord app = (ProcessRecord)msg.obj;
1739 synchronized (ActivityManagerService.this) {
1740 processStartTimedOutLocked(app);
1743 case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1744 ProcessRecord app = (ProcessRecord)msg.obj;
1745 synchronized (ActivityManagerService.this) {
1746 processContentProviderPublishTimedOutLocked(app);
1749 case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1750 synchronized (ActivityManagerService.this) {
1751 mActivityStarter.doPendingActivityLaunchesLocked(true);
1754 case KILL_APPLICATION_MSG: {
1755 synchronized (ActivityManagerService.this) {
1756 int appid = msg.arg1;
1757 boolean restart = (msg.arg2 == 1);
1758 Bundle bundle = (Bundle)msg.obj;
1759 String pkg = bundle.getString("pkg");
1760 String reason = bundle.getString("reason");
1761 forceStopPackageLocked(pkg, appid, restart, false, true, false,
1762 false, UserHandle.USER_ALL, reason);
1765 case FINALIZE_PENDING_INTENT_MSG: {
1766 ((PendingIntentRecord)msg.obj).completeFinalize();
1768 case POST_HEAVY_NOTIFICATION_MSG: {
1769 INotificationManager inm = NotificationManager.getService();
1774 ActivityRecord root = (ActivityRecord)msg.obj;
1775 ProcessRecord process = root.app;
1776 if (process == null) {
1781 Context context = mContext.createPackageContext(process.info.packageName, 0);
1782 String text = mContext.getString(R.string.heavy_weight_notification,
1783 context.getApplicationInfo().loadLabel(context.getPackageManager()));
1784 Notification notification = new Notification.Builder(context)
1785 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1789 .setColor(mContext.getColor(
1790 com.android.internal.R.color.system_notification_accent_color))
1791 .setContentTitle(text)
1793 mContext.getText(R.string.heavy_weight_notification_detail))
1794 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1795 root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1796 new UserHandle(root.userId)))
1799 int[] outId = new int[1];
1800 inm.enqueueNotificationWithTag("android", "android", null,
1801 R.string.heavy_weight_notification,
1802 notification, outId, root.userId);
1803 } catch (RuntimeException e) {
1804 Slog.w(ActivityManagerService.TAG,
1805 "Error showing notification for heavy-weight app", e);
1806 } catch (RemoteException e) {
1808 } catch (NameNotFoundException e) {
1809 Slog.w(TAG, "Unable to create context for heavy notification", e);
1812 case CANCEL_HEAVY_NOTIFICATION_MSG: {
1813 INotificationManager inm = NotificationManager.getService();
1818 inm.cancelNotificationWithTag("android", null,
1819 R.string.heavy_weight_notification, msg.arg1);
1820 } catch (RuntimeException e) {
1821 Slog.w(ActivityManagerService.TAG,
1822 "Error canceling notification for service", e);
1823 } catch (RemoteException e) {
1826 case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1827 synchronized (ActivityManagerService.this) {
1828 checkExcessivePowerUsageLocked(true);
1829 removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1830 Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1831 sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1834 case REPORT_MEM_USAGE_MSG: {
1835 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1836 Thread thread = new Thread() {
1837 @Override public void run() {
1838 reportMemUsage(memInfos);
1844 case REPORT_USER_SWITCH_MSG: {
1845 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1848 case CONTINUE_USER_SWITCH_MSG: {
1849 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1852 case USER_SWITCH_TIMEOUT_MSG: {
1853 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1856 case IMMERSIVE_MODE_LOCK_MSG: {
1857 final boolean nextState = (msg.arg1 != 0);
1858 if (mUpdateLock.isHeld() != nextState) {
1859 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1860 "Applying new update lock state '" + nextState
1861 + "' for " + (ActivityRecord)msg.obj);
1863 mUpdateLock.acquire();
1865 mUpdateLock.release();
1870 case PERSIST_URI_GRANTS_MSG: {
1871 writeGrantedUriPermissions();
1874 case REQUEST_ALL_PSS_MSG: {
1875 synchronized (ActivityManagerService.this) {
1876 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1880 case START_PROFILES_MSG: {
1881 synchronized (ActivityManagerService.this) {
1882 mUserController.startProfilesLocked();
1887 synchronized (ActivityManagerService.this) {
1888 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1889 ProcessRecord r = mLruProcesses.get(i);
1890 if (r.thread != null) {
1892 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
1893 } catch (RemoteException ex) {
1894 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
1901 case SYSTEM_USER_START_MSG: {
1902 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
1903 Integer.toString(msg.arg1), msg.arg1);
1904 mSystemServiceManager.startUser(msg.arg1);
1907 case SYSTEM_USER_UNLOCK_MSG: {
1908 final int userId = msg.arg1;
1909 mSystemServiceManager.unlockUser(userId);
1910 synchronized (ActivityManagerService.this) {
1911 mRecentTasks.loadUserRecentsLocked(userId);
1913 if (userId == UserHandle.USER_SYSTEM) {
1914 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
1916 installEncryptionUnawareProviders(userId);
1919 case SYSTEM_USER_CURRENT_MSG: {
1920 mBatteryStatsService.noteEvent(
1921 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
1922 Integer.toString(msg.arg2), msg.arg2);
1923 mBatteryStatsService.noteEvent(
1924 BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
1925 Integer.toString(msg.arg1), msg.arg1);
1926 mSystemServiceManager.switchUser(msg.arg1);
1929 case ENTER_ANIMATION_COMPLETE_MSG: {
1930 synchronized (ActivityManagerService.this) {
1931 ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
1932 if (r != null && r.app != null && r.app.thread != null) {
1934 r.app.thread.scheduleEnterAnimationComplete(r.appToken);
1935 } catch (RemoteException e) {
1941 case FINISH_BOOTING_MSG: {
1942 if (msg.arg1 != 0) {
1943 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
1945 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1947 if (msg.arg2 != 0) {
1948 enableScreenAfterBoot();
1952 case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
1954 Locale l = (Locale) msg.obj;
1955 IBinder service = ServiceManager.getService("mount");
1956 IMountService mountService = IMountService.Stub.asInterface(service);
1957 Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
1958 mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
1959 } catch (RemoteException e) {
1960 Log.e(TAG, "Error storing locale for decryption UI", e);
1964 case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
1965 synchronized (ActivityManagerService.this) {
1966 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1968 // Make a one-way callback to the listener
1969 mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
1970 } catch (RemoteException e){
1971 // Handled by the RemoteCallbackList
1974 mTaskStackListeners.finishBroadcast();
1978 case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
1979 synchronized (ActivityManagerService.this) {
1980 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1982 // Make a one-way callback to the listener
1983 mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
1984 } catch (RemoteException e){
1985 // Handled by the RemoteCallbackList
1988 mTaskStackListeners.finishBroadcast();
1992 case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
1993 synchronized (ActivityManagerService.this) {
1994 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
1996 // Make a one-way callback to the listener
1997 mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
1998 } catch (RemoteException e){
1999 // Handled by the RemoteCallbackList
2002 mTaskStackListeners.finishBroadcast();
2006 case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2007 synchronized (ActivityManagerService.this) {
2008 for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2010 // Make a one-way callback to the listener
2011 mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2012 } catch (RemoteException e){
2013 // Handled by the RemoteCallbackList
2016 mTaskStackListeners.finishBroadcast();
2020 case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2021 final int uid = msg.arg1;
2022 final byte[] firstPacket = (byte[]) msg.obj;
2024 synchronized (mPidsSelfLocked) {
2025 for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2026 final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2029 p.thread.notifyCleartextNetwork(firstPacket);
2030 } catch (RemoteException ignored) {
2037 case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2038 final String procName;
2040 final long memLimit;
2041 final String reportPackage;
2042 synchronized (ActivityManagerService.this) {
2043 procName = mMemWatchDumpProcName;
2044 uid = mMemWatchDumpUid;
2045 Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2047 val = mMemWatchProcesses.get(procName, 0);
2050 memLimit = val.first;
2051 reportPackage = val.second;
2054 reportPackage = null;
2057 if (procName == null) {
2061 if (DEBUG_PSS) Slog.d(TAG_PSS,
2062 "Showing dump heap notification from " + procName + "/" + uid);
2064 INotificationManager inm = NotificationManager.getService();
2069 String text = mContext.getString(R.string.dump_heap_notification, procName);
2072 Intent deleteIntent = new Intent();
2073 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2074 Intent intent = new Intent();
2075 intent.setClassName("android", DumpHeapActivity.class.getName());
2076 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2077 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2078 if (reportPackage != null) {
2079 intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2081 int userId = UserHandle.getUserId(uid);
2082 Notification notification = new Notification.Builder(mContext)
2083 .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2086 .setAutoCancel(true)
2088 .setColor(mContext.getColor(
2089 com.android.internal.R.color.system_notification_accent_color))
2090 .setContentTitle(text)
2092 mContext.getText(R.string.dump_heap_notification_detail))
2093 .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2094 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2095 new UserHandle(userId)))
2096 .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2097 deleteIntent, 0, UserHandle.SYSTEM))
2101 int[] outId = new int[1];
2102 inm.enqueueNotificationWithTag("android", "android", null,
2103 R.string.dump_heap_notification,
2104 notification, outId, userId);
2105 } catch (RuntimeException e) {
2106 Slog.w(ActivityManagerService.TAG,
2107 "Error showing notification for dump heap", e);
2108 } catch (RemoteException e) {
2111 case DELETE_DUMPHEAP_MSG: {
2112 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2113 DumpHeapActivity.JAVA_URI,
2114 Intent.FLAG_GRANT_READ_URI_PERMISSION
2115 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2116 UserHandle.myUserId());
2117 synchronized (ActivityManagerService.this) {
2118 mMemWatchDumpFile = null;
2119 mMemWatchDumpProcName = null;
2120 mMemWatchDumpPid = -1;
2121 mMemWatchDumpUid = -1;
2124 case FOREGROUND_PROFILE_CHANGED_MSG: {
2125 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2127 case REPORT_TIME_TRACKER_MSG: {
2128 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2129 tracker.deliverResult(mContext);
2131 case REPORT_USER_SWITCH_COMPLETE_MSG: {
2132 mUserController.dispatchUserSwitchComplete(msg.arg1);
2134 case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2135 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2137 connection.shutdown();
2138 } catch (RemoteException e) {
2139 Slog.w(TAG, "Error shutting down UiAutomationConnection");
2141 // Only a UiAutomation can set this flag and now that
2142 // it is finished we make sure it is reset to its default.
2143 mUserIsMonkey = false;
2145 case APP_BOOST_DEACTIVATE_MSG: {
2146 synchronized(ActivityManagerService.this) {
2148 if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2149 nativeMigrateFromBoost();
2151 mBoostStartTime = 0;
2153 Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2154 mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2159 case IDLE_UIDS_MSG: {
2162 case LOG_STACK_STATE: {
2163 synchronized (ActivityManagerService.this) {
2164 mStackSupervisor.logStackState();
2167 case VR_MODE_CHANGE_MSG: {
2168 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2169 final ActivityRecord r = (ActivityRecord) msg.obj;
2171 ComponentName requestedPackage;
2173 synchronized (ActivityManagerService.this) {
2174 vrMode = r.requestedVrComponent != null;
2175 requestedPackage = r.requestedVrComponent;
2177 if (mInVrMode != vrMode) {
2179 mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2182 vrService.setVrMode(vrMode, requestedPackage, userId);
2188 static final int COLLECT_PSS_BG_MSG = 1;
2190 final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2192 public void handleMessage(Message msg) {
2194 case COLLECT_PSS_BG_MSG: {
2195 long start = SystemClock.uptimeMillis();
2196 MemInfoReader memInfo = null;
2197 synchronized (ActivityManagerService.this) {
2198 if (mFullPssPending) {
2199 mFullPssPending = false;
2200 memInfo = new MemInfoReader();
2203 if (memInfo != null) {
2204 updateCpuStatsNow();
2205 long nativeTotalPss = 0;
2206 synchronized (mProcessCpuTracker) {
2207 final int N = mProcessCpuTracker.countStats();
2208 for (int j=0; j<N; j++) {
2209 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2210 if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2211 // This is definitely an application process; skip it.
2214 synchronized (mPidsSelfLocked) {
2215 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2216 // This is one of our own processes; skip it.
2220 nativeTotalPss += Debug.getPss(st.pid, null, null);
2223 memInfo.readMemInfo();
2224 synchronized (ActivityManagerService.this) {
2225 if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2226 + (SystemClock.uptimeMillis()-start) + "ms");
2227 final long cachedKb = memInfo.getCachedSizeKb();
2228 final long freeKb = memInfo.getFreeSizeKb();
2229 final long zramKb = memInfo.getZramTotalSizeKb();
2230 final long kernelKb = memInfo.getKernelUsedSizeKb();
2231 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2232 kernelKb*1024, nativeTotalPss*1024);
2233 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2239 long[] tmp = new long[2];
2245 synchronized (ActivityManagerService.this) {
2246 if (mPendingPssProcesses.size() <= 0) {
2247 if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2248 "Collected PSS of " + num + " processes in "
2249 + (SystemClock.uptimeMillis() - start) + "ms");
2250 mPendingPssProcesses.clear();
2253 proc = mPendingPssProcesses.remove(0);
2254 procState = proc.pssProcState;
2255 lastPssTime = proc.lastPssTime;
2256 if (proc.thread != null && procState == proc.setProcState
2257 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2258 < SystemClock.uptimeMillis()) {
2266 long pss = Debug.getPss(pid, tmp, null);
2267 synchronized (ActivityManagerService.this) {
2268 if (pss != 0 && proc.thread != null && proc.setProcState == procState
2269 && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2271 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2272 SystemClock.uptimeMillis());
2282 public void setSystemProcess() {
2284 ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2285 ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2286 ServiceManager.addService("meminfo", new MemBinder(this));
2287 ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2288 ServiceManager.addService("dbinfo", new DbBinder(this));
2289 if (MONITOR_CPU_USAGE) {
2290 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2292 ServiceManager.addService("permission", new PermissionController(this));
2293 ServiceManager.addService("processinfo", new ProcessInfoService(this));
2295 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2296 "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2297 mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2299 synchronized (this) {
2300 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2301 app.persistent = true;
2303 app.maxAdj = ProcessList.SYSTEM_ADJ;
2304 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2305 synchronized (mPidsSelfLocked) {
2306 mPidsSelfLocked.put(app.pid, app);
2308 updateLruProcessLocked(app, false, null);
2309 updateOomAdjLocked();
2311 } catch (PackageManager.NameNotFoundException e) {
2312 throw new RuntimeException(
2313 "Unable to find android system package", e);
2317 public void setWindowManager(WindowManagerService wm) {
2318 mWindowManager = wm;
2319 mStackSupervisor.setWindowManager(wm);
2320 mActivityStarter.setWindowManager(wm);
2323 public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2324 mUsageStatsService = usageStatsManager;
2327 public void startObservingNativeCrashes() {
2328 final NativeCrashListener ncl = new NativeCrashListener(this);
2332 public IAppOpsService getAppOpsService() {
2333 return mAppOpsService;
2336 static class MemBinder extends Binder {
2337 ActivityManagerService mActivityManagerService;
2338 MemBinder(ActivityManagerService activityManagerService) {
2339 mActivityManagerService = activityManagerService;
2343 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2344 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2345 != PackageManager.PERMISSION_GRANTED) {
2346 pw.println("Permission Denial: can't dump meminfo from from pid="
2347 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2348 + " without permission " + android.Manifest.permission.DUMP);
2352 mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, " ", args, false, null);
2356 static class GraphicsBinder extends Binder {
2357 ActivityManagerService mActivityManagerService;
2358 GraphicsBinder(ActivityManagerService activityManagerService) {
2359 mActivityManagerService = activityManagerService;
2363 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2364 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2365 != PackageManager.PERMISSION_GRANTED) {
2366 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2367 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2368 + " without permission " + android.Manifest.permission.DUMP);
2372 mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2376 static class DbBinder extends Binder {
2377 ActivityManagerService mActivityManagerService;
2378 DbBinder(ActivityManagerService activityManagerService) {
2379 mActivityManagerService = activityManagerService;
2383 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2384 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2385 != PackageManager.PERMISSION_GRANTED) {
2386 pw.println("Permission Denial: can't dump dbinfo from from pid="
2387 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2388 + " without permission " + android.Manifest.permission.DUMP);
2392 mActivityManagerService.dumpDbInfo(fd, pw, args);
2396 static class CpuBinder extends Binder {
2397 ActivityManagerService mActivityManagerService;
2398 CpuBinder(ActivityManagerService activityManagerService) {
2399 mActivityManagerService = activityManagerService;
2403 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2404 if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2405 != PackageManager.PERMISSION_GRANTED) {
2406 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2407 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2408 + " without permission " + android.Manifest.permission.DUMP);
2412 synchronized (mActivityManagerService.mProcessCpuTracker) {
2413 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2414 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2415 SystemClock.uptimeMillis()));
2420 public static final class Lifecycle extends SystemService {
2421 private final ActivityManagerService mService;
2423 public Lifecycle(Context context) {
2425 mService = new ActivityManagerService(context);
2429 public void onStart() {
2433 public ActivityManagerService getService() {
2438 // Note: This method is invoked on the main thread but may need to attach various
2439 // handlers to other threads. So take care to be explicit about the looper.
2440 public ActivityManagerService(Context systemContext) {
2441 mContext = systemContext;
2442 mFactoryTest = FactoryTest.getMode();
2443 mSystemThread = ActivityThread.currentActivityThread();
2445 Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2447 mHandlerThread = new ServiceThread(TAG,
2448 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2449 mHandlerThread.start();
2450 mHandler = new MainHandler(mHandlerThread.getLooper());
2451 mUiHandler = new UiHandler();
2453 mProcessStartLogger = new ProcessStartLogger();
2455 mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2456 "foreground", BROADCAST_FG_TIMEOUT, false);
2457 mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2458 "background", BROADCAST_BG_TIMEOUT, true);
2459 mBroadcastQueues[0] = mFgBroadcastQueue;
2460 mBroadcastQueues[1] = mBgBroadcastQueue;
2462 mServices = new ActiveServices(this);
2463 mProviderMap = new ProviderMap(this);
2464 mAppErrors = new AppErrors(mContext, this);
2466 // TODO: Move creation of battery stats service outside of activity manager service.
2467 File dataDir = Environment.getDataDirectory();
2468 File systemDir = new File(dataDir, "system");
2470 mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2471 mBatteryStatsService.getActiveStatistics().readLocked();
2472 mBatteryStatsService.scheduleWriteToDisk();
2473 mOnBattery = DEBUG_POWER ? true
2474 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2475 mBatteryStatsService.getActiveStatistics().setCallback(this);
2477 mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2479 mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2480 mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2481 new IAppOpsCallback.Stub() {
2482 @Override public void opChanged(int op, int uid, String packageName) {
2483 if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2484 if (mAppOpsService.checkOperation(op, uid, packageName)
2485 != AppOpsManager.MODE_ALLOWED) {
2486 runInBackgroundDisabled(uid);
2492 mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2494 mUserController = new UserController(this);
2496 GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2497 ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2499 mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2501 mConfiguration.setToDefaults();
2502 mConfiguration.setLocales(LocaleList.getDefault());
2504 mConfigurationSeq = mConfiguration.seq = 1;
2505 mProcessCpuTracker.init();
2507 mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2508 mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2509 mStackSupervisor = new ActivityStackSupervisor(this);
2510 mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2511 mRecentTasks = new RecentTasks(this, mStackSupervisor);
2513 mProcessCpuThread = new Thread("CpuTracker") {
2519 synchronized(this) {
2520 final long now = SystemClock.uptimeMillis();
2521 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2522 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2523 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2524 // + ", write delay=" + nextWriteDelay);
2525 if (nextWriteDelay < nextCpuDelay) {
2526 nextCpuDelay = nextWriteDelay;
2528 if (nextCpuDelay > 0) {
2529 mProcessCpuMutexFree.set(true);
2530 this.wait(nextCpuDelay);
2533 } catch (InterruptedException e) {
2535 updateCpuStatsNow();
2536 } catch (Exception e) {
2537 Slog.e(TAG, "Unexpected exception collecting process stats", e);
2543 Watchdog.getInstance().addMonitor(this);
2544 Watchdog.getInstance().addThread(mHandler);
2547 public void setSystemServiceManager(SystemServiceManager mgr) {
2548 mSystemServiceManager = mgr;
2551 public void setInstaller(Installer installer) {
2552 mInstaller = installer;
2555 private void start() {
2556 Process.removeAllProcessGroups();
2557 mProcessCpuThread.start();
2559 mBatteryStatsService.publish(mContext);
2560 mAppOpsService.publish(mContext);
2561 Slog.d("AppOps", "AppOpsService published");
2562 LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2565 void onUserStoppedLocked(int userId) {
2566 mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2569 public void initPowerManagement() {
2570 mStackSupervisor.initPowerManagement();
2571 mBatteryStatsService.initPowerManagement();
2572 mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2573 PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2574 mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2575 mVoiceWakeLock.setReferenceCounted(false);
2579 public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2580 throws RemoteException {
2581 if (code == SYSPROPS_TRANSACTION) {
2582 // We need to tell all apps about the system property change.
2583 ArrayList<IBinder> procs = new ArrayList<IBinder>();
2584 synchronized(this) {
2585 final int NP = mProcessNames.getMap().size();
2586 for (int ip=0; ip<NP; ip++) {
2587 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2588 final int NA = apps.size();
2589 for (int ia=0; ia<NA; ia++) {
2590 ProcessRecord app = apps.valueAt(ia);
2591 if (app.thread != null) {
2592 procs.add(app.thread.asBinder());
2598 int N = procs.size();
2599 for (int i=0; i<N; i++) {
2600 Parcel data2 = Parcel.obtain();
2602 procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2603 } catch (RemoteException e) {
2609 return super.onTransact(code, data, reply, flags);
2610 } catch (RuntimeException e) {
2611 // The activity manager only throws security exceptions, so let's
2613 if (!(e instanceof SecurityException)) {
2614 Slog.wtf(TAG, "Activity Manager Crash", e);
2620 void updateCpuStats() {
2621 final long now = SystemClock.uptimeMillis();
2622 if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2625 if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2626 synchronized (mProcessCpuThread) {
2627 mProcessCpuThread.notify();
2632 void updateCpuStatsNow() {
2633 synchronized (mProcessCpuTracker) {
2634 mProcessCpuMutexFree.set(false);
2635 final long now = SystemClock.uptimeMillis();
2636 boolean haveNewCpuStats = false;
2638 if (MONITOR_CPU_USAGE &&
2639 mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2640 mLastCpuTime.set(now);
2641 mProcessCpuTracker.update();
2642 if (mProcessCpuTracker.hasGoodLastStats()) {
2643 haveNewCpuStats = true;
2644 //Slog.i(TAG, mProcessCpu.printCurrentState());
2645 //Slog.i(TAG, "Total CPU usage: "
2646 // + mProcessCpu.getTotalCpuPercent() + "%");
2648 // Slog the cpu usage if the property is set.
2649 if ("true".equals(SystemProperties.get("events.cpu"))) {
2650 int user = mProcessCpuTracker.getLastUserTime();
2651 int system = mProcessCpuTracker.getLastSystemTime();
2652 int iowait = mProcessCpuTracker.getLastIoWaitTime();
2653 int irq = mProcessCpuTracker.getLastIrqTime();
2654 int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2655 int idle = mProcessCpuTracker.getLastIdleTime();
2657 int total = user + system + iowait + irq + softIrq + idle;
2658 if (total == 0) total = 1;
2660 EventLog.writeEvent(EventLogTags.CPU,
2661 ((user+system+iowait+irq+softIrq) * 100) / total,
2662 (user * 100) / total,
2663 (system * 100) / total,
2664 (iowait * 100) / total,
2665 (irq * 100) / total,
2666 (softIrq * 100) / total);
2671 final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2672 synchronized(bstats) {
2673 synchronized(mPidsSelfLocked) {
2674 if (haveNewCpuStats) {
2675 if (bstats.startAddingCpuLocked()) {
2678 final int N = mProcessCpuTracker.countStats();
2679 for (int i=0; i<N; i++) {
2680 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2684 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2685 totalUTime += st.rel_utime;
2686 totalSTime += st.rel_stime;
2688 BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2689 if (ps == null || !ps.isActive()) {
2690 pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2691 pr.info.uid, pr.processName);
2693 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2694 pr.curCpuTime += st.rel_utime + st.rel_stime;
2696 BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2697 if (ps == null || !ps.isActive()) {
2698 st.batteryStats = ps = bstats.getProcessStatsLocked(
2699 bstats.mapUid(st.uid), st.name);
2701 ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2704 final int userTime = mProcessCpuTracker.getLastUserTime();
2705 final int systemTime = mProcessCpuTracker.getLastSystemTime();
2706 final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2707 final int irqTime = mProcessCpuTracker.getLastIrqTime();
2708 final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2709 final int idleTime = mProcessCpuTracker.getLastIdleTime();
2710 bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2711 systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2716 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2717 mLastWriteTime = now;
2718 mBatteryStatsService.scheduleWriteToDisk();
2725 public void batteryNeedsCpuUpdate() {
2726 updateCpuStatsNow();
2730 public void batteryPowerChanged(boolean onBattery) {
2731 // When plugging in, update the CPU stats first before changing
2733 updateCpuStatsNow();
2734 synchronized (this) {
2735 synchronized(mPidsSelfLocked) {
2736 mOnBattery = DEBUG_POWER ? true : onBattery;
2742 public void batterySendBroadcast(Intent intent) {
2743 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2744 AppOpsManager.OP_NONE, null, false, false,
2745 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2749 * Initialize the application bind args. These are passed to each
2750 * process when the bindApplication() IPC is sent to the process. They're
2751 * lazily setup to make sure the services are running when they're asked for.
2753 private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2754 if (mAppBindArgs == null) {
2755 mAppBindArgs = new HashMap<>();
2757 // Isolated processes won't get this optimization, so that we don't
2758 // violate the rules about which services they have access to.
2760 // Setup the application init args
2761 mAppBindArgs.put("package", ServiceManager.getService("package"));
2762 mAppBindArgs.put("window", ServiceManager.getService("window"));
2763 mAppBindArgs.put(Context.ALARM_SERVICE,
2764 ServiceManager.getService(Context.ALARM_SERVICE));
2767 return mAppBindArgs;
2770 boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2771 if (r == null || mFocusedActivity == r) {
2775 if (!r.isFocusable()) {
2776 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2780 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2782 final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2783 if (wasDoingSetFocusedActivity) Slog.w(TAG,
2784 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2785 mDoingSetFocusedActivity = true;
2787 final ActivityRecord last = mFocusedActivity;
2788 mFocusedActivity = r;
2789 if (r.task.isApplicationTask()) {
2790 if (mCurAppTimeTracker != r.appTimeTracker) {
2791 // We are switching app tracking. Complete the current one.
2792 if (mCurAppTimeTracker != null) {
2793 mCurAppTimeTracker.stop();
2794 mHandler.obtainMessage(
2795 REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2796 mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2797 mCurAppTimeTracker = null;
2799 if (r.appTimeTracker != null) {
2800 mCurAppTimeTracker = r.appTimeTracker;
2801 startTimeTrackingFocusedActivityLocked();
2804 startTimeTrackingFocusedActivityLocked();
2807 r.appTimeTracker = null;
2809 // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2810 // TODO: Probably not, because we don't want to resume voice on switching
2811 // back to this activity
2812 if (r.task.voiceInteractor != null) {
2813 startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2815 finishRunningVoiceLocked();
2816 IVoiceInteractionSession session;
2817 if (last != null && ((session = last.task.voiceSession) != null
2818 || (session = last.voiceSession) != null)) {
2819 // We had been in a voice interaction session, but now focused has
2820 // move to something different. Just finish the session, we can't
2821 // return to it and retain the proper state and synchronization with
2822 // the voice interaction service.
2823 finishVoiceTask(session);
2826 if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
2827 mWindowManager.setFocusedApp(r.appToken, true);
2829 applyUpdateLockStateLocked(r);
2830 applyUpdateVrModeLocked(r);
2831 if (mFocusedActivity.userId != mLastFocusedUserId) {
2832 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2833 mHandler.obtainMessage(
2834 FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
2835 mLastFocusedUserId = mFocusedActivity.userId;
2838 // Log a warning if the focused app is changed during the process. This could
2839 // indicate a problem of the focus setting logic!
2840 if (mFocusedActivity != r) Slog.w(TAG,
2841 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
2842 mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
2844 EventLogTags.writeAmFocusedActivity(
2845 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
2846 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
2851 final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
2852 if (mFocusedActivity != goingAway) {
2856 final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
2857 if (focusedStack != null) {
2858 final ActivityRecord top = focusedStack.topActivity();
2859 if (top != null && top.userId != mLastFocusedUserId) {
2860 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
2861 mHandler.sendMessage(
2862 mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
2863 mLastFocusedUserId = top.userId;
2867 // Try to move focus to another activity if possible.
2868 if (setFocusedActivityLocked(
2869 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
2873 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
2874 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
2875 mFocusedActivity = null;
2876 EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
2880 public void setFocusedStack(int stackId) {
2881 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
2882 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
2883 final long callingId = Binder.clearCallingIdentity();
2885 synchronized (this) {
2886 final ActivityStack stack = mStackSupervisor.getStack(stackId);
2887 if (stack == null) {
2890 final ActivityRecord r = stack.topRunningActivityLocked();
2891 if (setFocusedActivityLocked(r, "setFocusedStack")) {
2892 mStackSupervisor.resumeFocusedStackTopActivityLocked();
2896 Binder.restoreCallingIdentity(callingId);
2901 public void setFocusedTask(int taskId) {
2902 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
2903 if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
2904 final long callingId = Binder.clearCallingIdentity();
2906 synchronized (this) {
2907 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
2911 final ActivityRecord r = task.topRunningActivityLocked();
2912 if (setFocusedActivityLocked(r, "setFocusedTask")) {
2913 mStackSupervisor.resumeFocusedStackTopActivityLocked();
2917 Binder.restoreCallingIdentity(callingId);
2921 /** Sets the task stack listener that gets callbacks when a task stack changes. */
2923 public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
2924 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
2925 synchronized (this) {
2926 if (listener != null) {
2927 mTaskStackListeners.register(listener);
2933 public void notifyActivityDrawn(IBinder token) {
2934 if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
2935 synchronized (this) {
2936 ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
2938 r.task.stack.notifyActivityDrawnLocked(r);
2943 final void applyUpdateLockStateLocked(ActivityRecord r) {
2944 // Modifications to the UpdateLock state are done on our handler, outside
2945 // the activity manager's locks. The new state is determined based on the
2946 // state *now* of the relevant activity record. The object is passed to
2947 // the handler solely for logging detail, not to be consulted/modified.
2948 final boolean nextState = r != null && r.immersive;
2949 mHandler.sendMessage(
2950 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
2953 final void applyUpdateVrModeLocked(ActivityRecord r) {
2954 mHandler.sendMessage(
2955 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
2958 final void showAskCompatModeDialogLocked(ActivityRecord r) {
2959 Message msg = Message.obtain();
2960 msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
2961 msg.obj = r.task.askedCompatMode ? null : r;
2962 mUiHandler.sendMessage(msg);
2965 private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
2966 String what, Object obj, ProcessRecord srcApp) {
2967 app.lastActivityTime = now;
2969 if (app.activities.size() > 0) {
2970 // Don't want to touch dependent processes that are hosting activities.
2974 int lrui = mLruProcesses.lastIndexOf(app);
2976 Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
2977 + what + " " + obj + " from " + srcApp);
2981 if (lrui >= index) {
2982 // Don't want to cause this to move dependent processes *back* in the
2983 // list as if they were less frequently used.
2987 if (lrui >= mLruProcessActivityStart) {
2988 // Don't want to touch dependent processes that are hosting activities.
2992 mLruProcesses.remove(lrui);
2996 if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
2997 + " in LRU list: " + app);
2998 mLruProcesses.add(index, app);
3002 static void killProcessGroup(int uid, int pid) {
3003 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
3004 Process.killProcessGroup(uid, pid);
3005 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3008 final void removeLruProcessLocked(ProcessRecord app) {
3009 int lrui = mLruProcesses.lastIndexOf(app);
3012 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3013 Process.killProcessQuiet(app.pid);
3014 killProcessGroup(app.info.uid, app.pid);
3016 if (lrui <= mLruProcessActivityStart) {
3017 mLruProcessActivityStart--;
3019 if (lrui <= mLruProcessServiceStart) {
3020 mLruProcessServiceStart--;
3022 mLruProcesses.remove(lrui);
3026 final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3027 ProcessRecord client) {
3028 final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3029 || app.treatLikeActivity;
3030 final boolean hasService = false; // not impl yet. app.services.size() > 0;
3031 if (!activityChange && hasActivity) {
3032 // The process has activities, so we are only allowing activity-based adjustments
3033 // to move it. It should be kept in the front of the list with other
3034 // processes that have activities, and we don't want those to change their
3035 // order except due to activity operations.
3040 final long now = SystemClock.uptimeMillis();
3041 app.lastActivityTime = now;
3043 // First a quick reject: if the app is already at the position we will
3044 // put it, then there is nothing to do.
3046 final int N = mLruProcesses.size();
3047 if (N > 0 && mLruProcesses.get(N-1) == app) {
3048 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3052 if (mLruProcessServiceStart > 0
3053 && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3054 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3059 int lrui = mLruProcesses.lastIndexOf(app);
3061 if (app.persistent && lrui >= 0) {
3062 // We don't care about the position of persistent processes, as long as
3063 // they are in the list.
3064 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3068 /* In progress: compute new position first, so we can avoid doing work
3069 if the process is not actually going to move. Not yet working.
3072 boolean inActivity = false, inService = false;
3074 // Process has activities, put it at the very tipsy-top.
3075 addIndex = mLruProcesses.size();
3076 nextIndex = mLruProcessServiceStart;
3078 } else if (hasService) {
3079 // Process has services, put it at the top of the service list.
3080 addIndex = mLruProcessActivityStart;
3081 nextIndex = mLruProcessServiceStart;
3085 // Process not otherwise of interest, it goes to the top of the non-service area.
3086 addIndex = mLruProcessServiceStart;
3087 if (client != null) {
3088 int clientIndex = mLruProcesses.lastIndexOf(client);
3089 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3091 if (clientIndex >= 0 && addIndex > clientIndex) {
3092 addIndex = clientIndex;
3095 nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3098 Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3099 + mLruProcessActivityStart + "): " + app);
3103 if (lrui < mLruProcessActivityStart) {
3104 mLruProcessActivityStart--;
3106 if (lrui < mLruProcessServiceStart) {
3107 mLruProcessServiceStart--;
3110 if (addIndex > lrui) {
3113 if (nextIndex > lrui) {
3117 mLruProcesses.remove(lrui);
3121 mLruProcesses.add(addIndex, app);
3123 mLruProcessActivityStart++;
3126 mLruProcessActivityStart++;
3132 final int N = mLruProcesses.size();
3133 if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3134 // Process doesn't have activities, but has clients with
3135 // activities... move it up, but one below the top (the top
3136 // should always have a real activity).
3137 if (DEBUG_LRU) Slog.d(TAG_LRU,
3138 "Adding to second-top of LRU activity list: " + app);
3139 mLruProcesses.add(N - 1, app);
3140 // To keep it from spamming the LRU list (by making a bunch of clients),
3141 // we will push down any other entries owned by the app.
3142 final int uid = app.info.uid;
3143 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3144 ProcessRecord subProc = mLruProcesses.get(i);
3145 if (subProc.info.uid == uid) {
3146 // We want to push this one down the list. If the process after
3147 // it is for the same uid, however, don't do so, because we don't
3148 // want them internally to be re-ordered.
3149 if (mLruProcesses.get(i - 1).info.uid != uid) {
3150 if (DEBUG_LRU) Slog.d(TAG_LRU,
3151 "Pushing uid " + uid + " swapping at " + i + ": "
3152 + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3153 ProcessRecord tmp = mLruProcesses.get(i);
3154 mLruProcesses.set(i, mLruProcesses.get(i - 1));
3155 mLruProcesses.set(i - 1, tmp);
3159 // A gap, we can stop here.
3164 // Process has activities, put it at the very tipsy-top.
3165 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3166 mLruProcesses.add(app);
3168 nextIndex = mLruProcessServiceStart;
3169 } else if (hasService) {
3170 // Process has services, put it at the top of the service list.
3171 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3172 mLruProcesses.add(mLruProcessActivityStart, app);
3173 nextIndex = mLruProcessServiceStart;
3174 mLruProcessActivityStart++;
3176 // Process not otherwise of interest, it goes to the top of the non-service area.
3177 int index = mLruProcessServiceStart;
3178 if (client != null) {
3179 // If there is a client, don't allow the process to be moved up higher
3180 // in the list than that client.
3181 int clientIndex = mLruProcesses.lastIndexOf(client);
3182 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3183 + " when updating " + app);
3184 if (clientIndex <= lrui) {
3185 // Don't allow the client index restriction to push it down farther in the
3186 // list than it already is.
3189 if (clientIndex >= 0 && index > clientIndex) {
3190 index = clientIndex;
3193 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3194 mLruProcesses.add(index, app);
3195 nextIndex = index-1;
3196 mLruProcessActivityStart++;
3197 mLruProcessServiceStart++;
3200 // If the app is currently using a content provider or service,
3201 // bump those processes as well.
3202 for (int j=app.connections.size()-1; j>=0; j--) {
3203 ConnectionRecord cr = app.connections.valueAt(j);
3204 if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3205 && cr.binding.service.app != null
3206 && cr.binding.service.app.lruSeq != mLruSeq
3207 && !cr.binding.service.app.persistent) {
3208 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3209 "service connection", cr, app);
3212 for (int j=app.conProviders.size()-1; j>=0; j--) {
3213 ContentProviderRecord cpr = app.conProviders.get(j).provider;
3214 if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3215 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3216 "provider reference", cpr, app);
3221 final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3222 if (uid == Process.SYSTEM_UID) {
3223 // The system gets to run in any process. If there are multiple
3224 // processes with the same uid, just pick the first (this
3225 // should never happen).
3226 SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3227 if (procs == null) return null;
3228 final int procCount = procs.size();
3229 for (int i = 0; i < procCount; i++) {
3230 final int procUid = procs.keyAt(i);
3231 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3232 // Don't use an app process or different user process for system component.
3235 return procs.valueAt(i);
3238 ProcessRecord proc = mProcessNames.get(processName, uid);
3239 if (false && proc != null && !keepIfLarge
3240 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3241 && proc.lastCachedPss >= 4000) {
3242 // Turn this condition on to cause killing to happen regularly, for testing.
3243 if (proc.baseProcessTracker != null) {
3244 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3246 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3247 } else if (proc != null && !keepIfLarge
3248 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3249 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3250 if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3251 if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3252 if (proc.baseProcessTracker != null) {
3253 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3255 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3261 void notifyPackageUse(String packageName) {
3262 IPackageManager pm = AppGlobals.getPackageManager();
3264 pm.notifyPackageUse(packageName);
3265 } catch (RemoteException e) {
3269 boolean isNextTransitionForward() {
3270 int transit = mWindowManager.getPendingAppTransition();
3271 return transit == TRANSIT_ACTIVITY_OPEN
3272 || transit == TRANSIT_TASK_OPEN
3273 || transit == TRANSIT_TASK_TO_FRONT;
3276 int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3277 String processName, String abiOverride, int uid, Runnable crashHandler) {
3278 synchronized(this) {
3279 ApplicationInfo info = new ApplicationInfo();
3280 // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3281 // For isolated processes, the former contains the parent's uid and the latter the
3282 // actual uid of the isolated process.
3283 // In the special case introduced by this method (which is, starting an isolated
3284 // process directly from the SystemServer without an actual parent app process) the
3285 // closest thing to a parent's uid is SYSTEM_UID.
3286 // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3287 // the |isolated| logic in the ProcessRecord constructor.
3288 info.uid = Process.SYSTEM_UID;
3289 info.processName = processName;
3290 info.className = entryPoint;
3291 info.packageName = "android";
3292 ProcessRecord proc = startProcessLocked(processName, info /* info */,
3293 false /* knownToBeDead */, 0 /* intentFlags */, "" /* hostingType */,
3294 null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3295 uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3297 return proc != null ? proc.pid : 0;
3301 final ProcessRecord startProcessLocked(String processName,
3302 ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3303 String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3304 boolean isolated, boolean keepIfLarge) {
3305 return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3306 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3307 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3308 null /* crashHandler */);
3311 final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3312 boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3313 boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3314 String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3315 long startTime = SystemClock.elapsedRealtime();
3318 app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3319 checkTime(startTime, "startProcess: after getProcessRecord");
3321 if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3322 // If we are in the background, then check to see if this process
3323 // is bad. If so, we will just silently fail.
3324 if (mAppErrors.isBadProcessLocked(info)) {
3325 if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3326 + "/" + info.processName);
3330 // When the user is explicitly starting a process, then clear its
3331 // crash count so that we won't make it bad until they see at
3332 // least one crash dialog again, and make the process good again
3333 // if it had been bad.
3334 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3335 + "/" + info.processName);
3336 mAppErrors.resetProcessCrashTimeLocked(info);
3337 if (mAppErrors.isBadProcessLocked(info)) {
3338 EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3339 UserHandle.getUserId(info.uid), info.uid,
3341 mAppErrors.clearBadProcessLocked(info);
3348 // If this is an isolated process, it can't re-use an existing process.
3352 // app launch boost for big.little configurations
3353 // use cpusets to migrate freshly launched tasks to big cores
3354 synchronized(ActivityManagerService.this) {
3355 nativeMigrateToBoost();
3357 mBoostStartTime = SystemClock.uptimeMillis();
3358 Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3359 mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3362 // We don't have to do anything more if:
3363 // (1) There is an existing application record; and
3364 // (2) The caller doesn't think it is dead, OR there is no thread
3365 // object attached to it so we know it couldn't have crashed; and
3366 // (3) There is a pid assigned to it, so it is either starting or
3368 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3369 + " app=" + app + " knownToBeDead=" + knownToBeDead
3370 + " thread=" + (app != null ? app.thread : null)
3371 + " pid=" + (app != null ? app.pid : -1));
3372 if (app != null && app.pid > 0) {
3373 if (!knownToBeDead || app.thread == null) {
3374 // We already have the app running, or are waiting for it to
3375 // come up (we have a pid but not yet its thread), so keep it.
3376 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3377 // If this is a new package in the process, add the package to the list
3378 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3379 checkTime(startTime, "startProcess: done, added package to proc");
3383 // An application record is attached to a previous process,
3385 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3386 checkTime(startTime, "startProcess: bad proc running, killing");
3387 killProcessGroup(app.info.uid, app.pid);
3388 handleAppDiedLocked(app, true, true);
3389 checkTime(startTime, "startProcess: done killing old proc");
3392 String hostingNameStr = hostingName != null
3393 ? hostingName.flattenToShortString() : null;
3396 checkTime(startTime, "startProcess: creating new process record");
3397 app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3399 Slog.w(TAG, "Failed making new process record for "
3400 + processName + "/" + info.uid + " isolated=" + isolated);
3403 app.crashHandler = crashHandler;
3404 checkTime(startTime, "startProcess: done creating new process record");
3406 // If this is a new package in the process, add the package to the list
3407 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3408 checkTime(startTime, "startProcess: added package to existing proc");
3411 // If the system is not ready yet, then hold off on starting this
3412 // process until it is.
3413 if (!mProcessesReady
3414 && !isAllowedWhileBooting(info)
3415 && !allowWhileBooting) {
3416 if (!mProcessesOnHold.contains(app)) {
3417 mProcessesOnHold.add(app);
3419 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3420 "System not ready, putting on hold: " + app);
3421 checkTime(startTime, "startProcess: returning with proc on hold");
3425 checkTime(startTime, "startProcess: stepping in to startProcess");
3427 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3428 checkTime(startTime, "startProcess: done starting proc!");
3429 return (app.pid != 0) ? app : null;
3432 boolean isAllowedWhileBooting(ApplicationInfo ai) {
3433 return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3436 private final void startProcessLocked(ProcessRecord app,
3437 String hostingType, String hostingNameStr) {
3438 startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3439 null /* entryPoint */, null /* entryPointArgs */);
3442 private final void startProcessLocked(ProcessRecord app, String hostingType,
3443 String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3444 long startTime = SystemClock.elapsedRealtime();
3445 if (app.pid > 0 && app.pid != MY_PID) {
3446 checkTime(startTime, "startProcess: removing from pids map");
3447 synchronized (mPidsSelfLocked) {
3448 mPidsSelfLocked.remove(app.pid);
3449 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3451 checkTime(startTime, "startProcess: done removing from pids map");
3455 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3456 "startProcessLocked removing on hold: " + app);
3457 mProcessesOnHold.remove(app);
3459 checkTime(startTime, "startProcess: starting to update cpu stats");
3461 checkTime(startTime, "startProcess: done updating cpu stats");
3465 final int userId = UserHandle.getUserId(app.uid);
3466 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3467 } catch (RemoteException e) {
3468 throw e.rethrowAsRuntimeException();
3473 int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3474 if (!app.isolated) {
3475 int[] permGids = null;
3477 checkTime(startTime, "startProcess: getting gids from package manager");
3478 final IPackageManager pm = AppGlobals.getPackageManager();
3479 permGids = pm.getPackageGids(app.info.packageName,
3480 MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3481 MountServiceInternal mountServiceInternal = LocalServices.getService(
3482 MountServiceInternal.class);
3483 mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3484 app.info.packageName);
3485 } catch (RemoteException e) {
3486 throw e.rethrowAsRuntimeException();
3490 * Add shared application and profile GIDs so applications can share some
3491 * resources like shared libraries and access user-wide resources
3493 if (ArrayUtils.isEmpty(permGids)) {
3496 gids = new int[permGids.length + 2];
3497 System.arraycopy(permGids, 0, gids, 2, permGids.length);
3499 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3500 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3502 checkTime(startTime, "startProcess: building args");
3503 if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3504 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3505 && mTopComponent != null
3506 && app.processName.equals(mTopComponent.getPackageName())) {
3509 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3510 && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3515 if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3516 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3517 // Also turn on CheckJNI for debuggable apps. It's quite
3518 // awkward to turn on otherwise.
3519 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3521 // Run the app in safe mode if its manifest requests so or the
3522 // system is booted in safe mode.
3523 if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3524 mSafeMode == true) {
3525 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3527 if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3528 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3530 String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3531 if ("true".equals(genDebugInfoProperty)) {
3532 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3534 if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3535 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3537 if ("1".equals(SystemProperties.get("debug.assert"))) {
3538 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3540 if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3541 // Enable all debug flags required by the native debugger.
3542 debugFlags |= Zygote.DEBUG_ALWAYS_JIT; // Don't interpret anything
3543 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3544 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE; // Disbale optimizations
3545 mNativeDebuggingApp = null;
3548 String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3549 if (requiredAbi == null) {
3550 requiredAbi = Build.SUPPORTED_ABIS[0];
3553 String instructionSet = null;
3554 if (app.info.primaryCpuAbi != null) {
3555 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3559 app.requiredAbi = requiredAbi;
3560 app.instructionSet = instructionSet;
3562 // Start the process. It will either succeed and return a result containing
3563 // the PID of the new process, or else throw a RuntimeException.
3564 boolean isActivityProcess = (entryPoint == null);
3565 if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3566 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3568 checkTime(startTime, "startProcess: asking zygote to start proc");
3569 Process.ProcessStartResult startResult = Process.start(entryPoint,
3570 app.processName, uid, uid, gids, debugFlags, mountExternal,
3571 app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3572 app.info.dataDir, entryPointArgs);
3573 checkTime(startTime, "startProcess: returned from zygote!");
3574 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3577 mBatteryStatsService.addIsolatedUid(app.uid, app.info.uid);
3579 mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3580 checkTime(startTime, "startProcess: done updating battery stats");
3582 EventLog.writeEvent(EventLogTags.AM_PROC_START,
3583 UserHandle.getUserId(uid), startResult.pid, uid,
3584 app.processName, hostingType,
3585 hostingNameStr != null ? hostingNameStr : "");
3587 mProcessStartLogger.logIfNeededLocked(app, startResult);
3589 if (app.persistent) {
3590 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3593 if (DEBUG_PROCESSES) {
3594 checkTime(startTime, "startProcess: building log message");
3595 StringBuilder buf = mStringBuilder;
3597 buf.append("Start proc ");
3598 buf.append(startResult.pid);
3600 buf.append(app.processName);
3602 UserHandle.formatUid(buf, uid);
3603 if (!isActivityProcess) {
3605 buf.append(entryPoint);
3608 buf.append(" for ");
3609 buf.append(hostingType);
3610 if (hostingNameStr != null) {
3612 buf.append(hostingNameStr);
3614 Slog.i(TAG, buf.toString());
3616 app.setPid(startResult.pid);
3617 app.usingWrapper = startResult.usingWrapper;
3618 app.removed = false;
3620 app.killedByAm = false;
3621 checkTime(startTime, "startProcess: starting to update pids map");
3622 synchronized (mPidsSelfLocked) {
3623 this.mPidsSelfLocked.put(startResult.pid, app);
3624 if (isActivityProcess) {
3625 Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3627 mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3628 ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3631 checkTime(startTime, "startProcess: done updating pids map");
3632 } catch (RuntimeException e) {
3633 // XXX do better error recovery.
3635 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
3637 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
3639 Slog.e(TAG, "Failure starting process " + app.processName, e);
3643 void updateUsageStats(ActivityRecord component, boolean resumed) {
3644 if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3645 "updateUsageStats: comp=" + component + "res=" + resumed);
3646 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3648 if (mUsageStatsService != null) {
3649 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3650 UsageEvents.Event.MOVE_TO_FOREGROUND);
3652 synchronized (stats) {
3653 stats.noteActivityResumedLocked(component.app.uid);
3656 if (mUsageStatsService != null) {
3657 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3658 UsageEvents.Event.MOVE_TO_BACKGROUND);
3660 synchronized (stats) {
3661 stats.noteActivityPausedLocked(component.app.uid);
3666 Intent getHomeIntent() {
3667 Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3668 intent.setComponent(mTopComponent);
3669 intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3670 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3671 intent.addCategory(Intent.CATEGORY_HOME);
3676 boolean startHomeActivityLocked(int userId, String reason) {
3677 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3678 && mTopAction == null) {
3679 // We are running in factory test mode, but unable to find
3680 // the factory test app, so just sit around displaying the
3681 // error message and don't try to start anything.
3684 Intent intent = getHomeIntent();
3685 ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3686 if (aInfo != null) {
3687 intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3688 // Don't do this if the home app is currently being
3690 aInfo = new ActivityInfo(aInfo);
3691 aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3692 ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3693 aInfo.applicationInfo.uid, true);
3694 if (app == null || app.instrumentationClass == null) {
3695 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3696 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3703 private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3704 ActivityInfo ai = null;
3705 ComponentName comp = intent.getComponent();
3709 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3711 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3713 intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3717 ai = info.activityInfo;
3720 } catch (RemoteException e) {
3728 * Starts the "new version setup screen" if appropriate.
3730 void startSetupActivityLocked() {
3731 // Only do this once per boot.
3732 if (mCheckedForSetup) {
3736 // We will show this screen if the current one is a different
3737 // version than the last one shown, and we are not running in
3738 // low-level factory test mode.
3739 final ContentResolver resolver = mContext.getContentResolver();
3740 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3741 Settings.Global.getInt(resolver,
3742 Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3743 mCheckedForSetup = true;
3745 // See if we should be showing the platform update setup UI.
3746 final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3747 final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3748 PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3749 if (!ris.isEmpty()) {
3750 final ResolveInfo ri = ris.get(0);
3751 String vers = ri.activityInfo.metaData != null
3752 ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3754 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3755 vers = ri.activityInfo.applicationInfo.metaData.getString(
3756 Intent.METADATA_SETUP_VERSION);
3758 String lastVers = Settings.Secure.getString(
3759 resolver, Settings.Secure.LAST_SETUP_SHOWN);
3760 if (vers != null && !vers.equals(lastVers)) {
3761 intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
3762 intent.setComponent(new ComponentName(
3763 ri.activityInfo.packageName, ri.activityInfo.name));
3764 mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
3765 null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
3766 null, 0, 0, 0, null, false, false, null, null, null);
3772 CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
3773 return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
3776 void enforceNotIsolatedCaller(String caller) {
3777 if (UserHandle.isIsolated(Binder.getCallingUid())) {
3778 throw new SecurityException("Isolated process not allowed to call " + caller);
3782 void enforceShellRestriction(String restriction, int userHandle) {
3783 if (Binder.getCallingUid() == Process.SHELL_UID) {
3784 if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
3785 throw new SecurityException("Shell does not have permission to access user "
3792 public int getFrontActivityScreenCompatMode() {
3793 enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
3794 synchronized (this) {
3795 return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
3800 public void setFrontActivityScreenCompatMode(int mode) {
3801 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3802 "setFrontActivityScreenCompatMode");
3803 synchronized (this) {
3804 mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
3809 public int getPackageScreenCompatMode(String packageName) {
3810 enforceNotIsolatedCaller("getPackageScreenCompatMode");
3811 synchronized (this) {
3812 return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
3817 public void setPackageScreenCompatMode(String packageName, int mode) {
3818 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3819 "setPackageScreenCompatMode");
3820 synchronized (this) {
3821 mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
3826 public boolean getPackageAskScreenCompat(String packageName) {
3827 enforceNotIsolatedCaller("getPackageAskScreenCompat");
3828 synchronized (this) {
3829 return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
3834 public void setPackageAskScreenCompat(String packageName, boolean ask) {
3835 enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
3836 "setPackageAskScreenCompat");
3837 synchronized (this) {
3838 mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
3842 private boolean hasUsageStatsPermission(String callingPackage) {
3843 final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
3844 Binder.getCallingUid(), callingPackage);
3845 if (mode == AppOpsManager.MODE_DEFAULT) {
3846 return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
3847 == PackageManager.PERMISSION_GRANTED;
3849 return mode == AppOpsManager.MODE_ALLOWED;
3853 public int getPackageProcessState(String packageName, String callingPackage) {
3854 if (!hasUsageStatsPermission(callingPackage)) {
3855 enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
3856 "getPackageProcessState");
3859 int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
3860 synchronized (this) {
3861 for (int i=mLruProcesses.size()-1; i>=0; i--) {
3862 final ProcessRecord proc = mLruProcesses.get(i);
3863 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
3864 || procState > proc.setProcState) {
3865 boolean found = false;
3866 for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
3867 if (proc.pkgList.keyAt(j).equals(packageName)) {
3868 procState = proc.setProcState;
3872 if (proc.pkgDeps != null && !found) {
3873 for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
3874 if (proc.pkgDeps.valueAt(j).equals(packageName)) {
3875 procState = proc.setProcState;
3887 public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
3888 synchronized (this) {
3889 final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
3893 if (app.trimMemoryLevel < level && app.thread != null &&
3894 (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
3895 app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
3897 app.thread.scheduleTrimMemory(level);
3898 app.trimMemoryLevel = level;
3900 } catch (RemoteException e) {
3901 // Fallthrough to failure case.
3908 private void dispatchProcessesChanged() {
3910 synchronized (this) {
3911 N = mPendingProcessChanges.size();
3912 if (mActiveProcessChanges.length < N) {
3913 mActiveProcessChanges = new ProcessChangeItem[N];
3915 mPendingProcessChanges.toArray(mActiveProcessChanges);
3916 mPendingProcessChanges.clear();
3917 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3918 "*** Delivering " + N + " process changes");
3921 int i = mProcessObservers.beginBroadcast();
3924 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3925 if (observer != null) {
3927 for (int j=0; j<N; j++) {
3928 ProcessChangeItem item = mActiveProcessChanges[j];
3929 if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
3930 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3931 "ACTIVITIES CHANGED pid=" + item.pid + " uid="
3932 + item.uid + ": " + item.foregroundActivities);
3933 observer.onForegroundActivitiesChanged(item.pid, item.uid,
3934 item.foregroundActivities);
3936 if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
3937 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
3938 "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
3939 + ": " + item.processState);
3940 observer.onProcessStateChanged(item.pid, item.uid, item.processState);
3943 } catch (RemoteException e) {
3947 mProcessObservers.finishBroadcast();
3949 synchronized (this) {
3950 for (int j=0; j<N; j++) {
3951 mAvailProcessChanges.add(mActiveProcessChanges[j]);
3956 private void dispatchProcessDied(int pid, int uid) {
3957 int i = mProcessObservers.beginBroadcast();
3960 final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
3961 if (observer != null) {
3963 observer.onProcessDied(pid, uid);
3964 } catch (RemoteException e) {
3968 mProcessObservers.finishBroadcast();
3971 private void dispatchUidsChanged() {
3973 synchronized (this) {
3974 N = mPendingUidChanges.size();
3975 if (mActiveUidChanges.length < N) {
3976 mActiveUidChanges = new UidRecord.ChangeItem[N];
3978 for (int i=0; i<N; i++) {
3979 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
3980 mActiveUidChanges[i] = change;
3981 if (change.uidRecord != null) {
3982 change.uidRecord.pendingChange = null;
3983 change.uidRecord = null;
3986 mPendingUidChanges.clear();
3987 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
3988 "*** Delivering " + N + " uid changes");
3991 if (mLocalPowerManager != null) {
3992 for (int j=0; j<N; j++) {
3993 UidRecord.ChangeItem item = mActiveUidChanges[j];
3994 if (item.change == UidRecord.CHANGE_GONE
3995 || item.change == UidRecord.CHANGE_GONE_IDLE) {
3996 mLocalPowerManager.uidGone(item.uid);
3998 mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4003 int i = mUidObservers.beginBroadcast();
4006 final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4007 final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4008 if (observer != null) {
4010 for (int j=0; j<N; j++) {
4011 UidRecord.ChangeItem item = mActiveUidChanges[j];
4012 final int change = item.change;
4013 UidRecord validateUid = null;
4014 if (VALIDATE_UID_STATES && i == 0) {
4015 validateUid = mValidateUids.get(item.uid);
4016 if (validateUid == null && change != UidRecord.CHANGE_GONE
4017 && change != UidRecord.CHANGE_GONE_IDLE) {
4018 validateUid = new UidRecord(item.uid);
4019 mValidateUids.put(item.uid, validateUid);
4022 if (change == UidRecord.CHANGE_IDLE
4023 || change == UidRecord.CHANGE_GONE_IDLE) {
4024 if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4025 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4026 "UID idle uid=" + item.uid);
4027 observer.onUidIdle(item.uid);
4029 if (VALIDATE_UID_STATES && i == 0) {
4030 if (validateUid != null) {
4031 validateUid.idle = true;
4034 } else if (change == UidRecord.CHANGE_ACTIVE) {
4035 if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4036 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4037 "UID active uid=" + item.uid);
4038 observer.onUidActive(item.uid);
4040 if (VALIDATE_UID_STATES && i == 0) {
4041 validateUid.idle = false;
4044 if (change == UidRecord.CHANGE_GONE
4045 || change == UidRecord.CHANGE_GONE_IDLE) {
4046 if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4047 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4048 "UID gone uid=" + item.uid);
4049 observer.onUidGone(item.uid);
4051 if (VALIDATE_UID_STATES && i == 0) {
4052 if (validateUid != null) {
4053 mValidateUids.remove(item.uid);
4057 if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4058 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4059 "UID CHANGED uid=" + item.uid
4060 + ": " + item.processState);
4061 observer.onUidStateChanged(item.uid, item.processState);
4063 if (VALIDATE_UID_STATES && i == 0) {
4064 validateUid.curProcState = validateUid.setProcState
4065 = item.processState;
4069 } catch (RemoteException e) {
4073 mUidObservers.finishBroadcast();
4075 synchronized (this) {
4076 for (int j=0; j<N; j++) {
4077 mAvailUidChanges.add(mActiveUidChanges[j]);
4083 public final int startActivity(IApplicationThread caller, String callingPackage,
4084 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4085 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4086 return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4087 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4088 UserHandle.getCallingUserId());
4091 final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4092 enforceNotIsolatedCaller("ActivityContainer.startActivity");
4093 final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4094 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4095 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4097 // TODO: Switch to user app stacks here.
4098 String mimeType = intent.getType();
4099 final Uri data = intent.getData();
4100 if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4101 mimeType = getProviderMimeType(data, userId);
4103 container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4105 intent.addFlags(FORCE_NEW_TASK_FLAGS);
4106 return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4107 null, 0, 0, null, null, null, null, false, userId, container, null);
4111 public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4112 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4113 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4114 enforceNotIsolatedCaller("startActivity");
4115 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4116 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4117 // TODO: Switch to user app stacks here.
4118 return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4119 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4120 profilerInfo, null, null, bOptions, false, userId, null, null);
4124 public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4125 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4126 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4129 // This is very dangerous -- it allows you to perform a start activity (including
4130 // permission grants) as any app that may launch one of your own activities. So
4131 // we will only allow this to be done from activities that are part of the core framework,
4132 // and then only when they are running as the system.
4133 final ActivityRecord sourceRecord;
4134 final int targetUid;
4135 final String targetPackage;
4136 synchronized (this) {
4137 if (resultTo == null) {
4138 throw new SecurityException("Must be called from an activity");
4140 sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4141 if (sourceRecord == null) {
4142 throw new SecurityException("Called with bad activity token: " + resultTo);
4144 if (!sourceRecord.info.packageName.equals("android")) {
4145 throw new SecurityException(
4146 "Must be called from an activity that is declared in the android package");
4148 if (sourceRecord.app == null) {
4149 throw new SecurityException("Called without a process attached to activity");
4151 if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4152 // This is still okay, as long as this activity is running under the
4153 // uid of the original calling activity.
4154 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4155 throw new SecurityException(
4156 "Calling activity in uid " + sourceRecord.app.uid
4157 + " must be system uid or original calling uid "
4158 + sourceRecord.launchedFromUid);
4161 if (ignoreTargetSecurity) {
4162 if (intent.getComponent() == null) {
4163 throw new SecurityException(
4164 "Component must be specified with ignoreTargetSecurity");
4166 if (intent.getSelector() != null) {
4167 throw new SecurityException(
4168 "Selector not allowed with ignoreTargetSecurity");
4171 targetUid = sourceRecord.launchedFromUid;
4172 targetPackage = sourceRecord.launchedFromPackage;
4175 if (userId == UserHandle.USER_NULL) {
4176 userId = UserHandle.getUserId(sourceRecord.app.uid);
4179 // TODO: Switch to user app stacks here.
4181 int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4182 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4183 null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4185 } catch (SecurityException e) {
4186 // XXX need to figure out how to propagate to original app.
4187 // A SecurityException here is generally actually a fault of the original
4188 // calling activity (such as a fairly granting permissions), so propagate it
4191 StringBuilder msg = new StringBuilder();
4192 msg.append("While launching");
4193 msg.append(intent.toString());
4195 msg.append(e.getMessage());
4202 public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4203 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4204 int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4205 enforceNotIsolatedCaller("startActivityAndWait");
4206 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4207 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4208 WaitResult res = new WaitResult();
4209 // TODO: Switch to user app stacks here.
4210 mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4211 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4212 bOptions, false, userId, null, null);
4217 public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4218 Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4219 int startFlags, Configuration config, Bundle bOptions, int userId) {
4220 enforceNotIsolatedCaller("startActivityWithConfig");
4221 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4222 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4223 // TODO: Switch to user app stacks here.
4224 int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4225 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4226 null, null, config, bOptions, false, userId, null, null);
4231 public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4232 Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4233 int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4234 throws TransactionTooLargeException {
4235 enforceNotIsolatedCaller("startActivityIntentSender");
4236 // Refuse possible leaked file descriptors
4237 if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4238 throw new IllegalArgumentException("File descriptors passed in Intent");
4241 IIntentSender sender = intent.getTarget();
4242 if (!(sender instanceof PendingIntentRecord)) {
4243 throw new IllegalArgumentException("Bad PendingIntent object");
4246 PendingIntentRecord pir = (PendingIntentRecord)sender;
4248 synchronized (this) {
4249 // If this is coming from the currently resumed activity, it is
4250 // effectively saying that app switches are allowed at this point.
4251 final ActivityStack stack = getFocusedStack();
4252 if (stack.mResumedActivity != null &&
4253 stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4254 mAppSwitchesAllowedTime = 0;
4257 int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4258 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4263 public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4264 Intent intent, String resolvedType, IVoiceInteractionSession session,
4265 IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4266 Bundle bOptions, int userId) {
4267 if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4268 != PackageManager.PERMISSION_GRANTED) {
4269 String msg = "Permission Denial: startVoiceActivity() from pid="
4270 + Binder.getCallingPid()
4271 + ", uid=" + Binder.getCallingUid()
4272 + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4274 throw new SecurityException(msg);
4276 if (session == null || interactor == null) {
4277 throw new NullPointerException("null session or interactor");
4279 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4280 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4281 // TODO: Switch to user app stacks here.
4282 return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4283 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4284 null, bOptions, false, userId, null, null);
4288 public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4289 throws RemoteException {
4290 Slog.i(TAG, "Activity tried to startVoiceInteraction");
4291 synchronized (this) {
4292 ActivityRecord activity = getFocusedStack().topActivity();
4293 if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4294 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4296 if (mRunningVoice != null || activity.task.voiceSession != null
4297 || activity.voiceSession != null) {
4298 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4301 if (activity.pendingVoiceInteractionStart) {
4302 Slog.w(TAG, "Pending start of voice interaction already.");
4305 activity.pendingVoiceInteractionStart = true;
4307 LocalServices.getService(VoiceInteractionManagerInternal.class)
4308 .startLocalVoiceInteraction(callingActivity, options);
4312 public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4313 LocalServices.getService(VoiceInteractionManagerInternal.class)
4314 .stopLocalVoiceInteraction(callingActivity);
4318 public boolean supportsLocalVoiceInteraction() throws RemoteException {
4319 return LocalServices.getService(VoiceInteractionManagerInternal.class)
4320 .supportsLocalVoiceInteraction();
4323 void onLocalVoiceInteractionStartedLocked(IBinder activity,
4324 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4325 ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4326 if (activityToCallback == null) return;
4327 activityToCallback.setVoiceSessionLocked(voiceSession);
4329 // Inform the activity
4331 activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4333 long token = Binder.clearCallingIdentity();
4335 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4337 Binder.restoreCallingIdentity(token);
4339 // TODO: VI Should we cache the activity so that it's easier to find later
4340 // rather than scan through all the stacks and activities?
4341 } catch (RemoteException re) {
4342 activityToCallback.clearVoiceSessionLocked();
4343 // TODO: VI Should this terminate the voice session?
4348 public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4349 synchronized (this) {
4350 if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4352 mVoiceWakeLock.acquire();
4354 mVoiceWakeLock.release();
4361 public boolean startNextMatchingActivity(IBinder callingActivity,
4362 Intent intent, Bundle bOptions) {
4363 // Refuse possible leaked file descriptors
4364 if (intent != null && intent.hasFileDescriptors() == true) {
4365 throw new IllegalArgumentException("File descriptors passed in Intent");
4367 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4369 synchronized (this) {
4370 final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4372 ActivityOptions.abort(options);
4375 if (r.app == null || r.app.thread == null) {
4376 // The caller is not running... d'oh!
4377 ActivityOptions.abort(options);
4380 intent = new Intent(intent);
4381 // The caller is not allowed to change the data.
4382 intent.setDataAndType(r.intent.getData(), r.intent.getType());
4383 // And we are resetting to find the next component...
4384 intent.setComponent(null);
4386 final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4388 ActivityInfo aInfo = null;
4390 List<ResolveInfo> resolves =
4391 AppGlobals.getPackageManager().queryIntentActivities(
4392 intent, r.resolvedType,
4393 PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4394 UserHandle.getCallingUserId()).getList();
4396 // Look for the original activity in the list...
4397 final int N = resolves != null ? resolves.size() : 0;
4398 for (int i=0; i<N; i++) {
4399 ResolveInfo rInfo = resolves.get(i);
4400 if (rInfo.activityInfo.packageName.equals(r.packageName)
4401 && rInfo.activityInfo.name.equals(r.info.name)) {
4402 // We found the current one... the next matching is
4406 aInfo = resolves.get(i).activityInfo;
4409 Slog.v(TAG, "Next matching activity: found current " + r.packageName
4410 + "/" + r.info.name);
4411 Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4412 ? "null" : aInfo.packageName + "/" + aInfo.name));
4417 } catch (RemoteException e) {
4420 if (aInfo == null) {
4421 // Nobody who is next!
4422 ActivityOptions.abort(options);
4423 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4427 intent.setComponent(new ComponentName(
4428 aInfo.applicationInfo.packageName, aInfo.name));
4429 intent.setFlags(intent.getFlags()&~(
4430 Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4431 Intent.FLAG_ACTIVITY_CLEAR_TOP|
4432 Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4433 Intent.FLAG_ACTIVITY_NEW_TASK));
4435 // Okay now we need to start the new activity, replacing the
4436 // currently running activity. This is a little tricky because
4437 // we want to start the new one as if the current one is finished,
4438 // but not finish the current one first so that there is no flicker.
4440 final boolean wasFinishing = r.finishing;
4443 // Propagate reply information over to the new activity.
4444 final ActivityRecord resultTo = r.resultTo;
4445 final String resultWho = r.resultWho;
4446 final int requestCode = r.requestCode;
4448 if (resultTo != null) {
4449 resultTo.removeResultsLocked(r, resultWho, requestCode);
4452 final long origId = Binder.clearCallingIdentity();
4453 int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4454 null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4455 null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4456 r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4457 false, false, null, null, null);
4458 Binder.restoreCallingIdentity(origId);
4460 r.finishing = wasFinishing;
4461 if (res != ActivityManager.START_SUCCESS) {
4469 public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4470 if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4471 String msg = "Permission Denial: startActivityFromRecents called without " +
4472 START_TASKS_FROM_RECENTS;
4474 throw new SecurityException(msg);
4476 final long origId = Binder.clearCallingIdentity();
4478 return startActivityFromRecentsInner(taskId, bOptions);
4480 Binder.restoreCallingIdentity(origId);
4484 final int startActivityFromRecentsInner(int taskId, Bundle bOptions) {
4485 final TaskRecord task;
4486 final int callingUid;
4487 final String callingPackage;
4488 final Intent intent;
4490 synchronized (this) {
4491 final ActivityOptions activityOptions = (bOptions != null)
4492 ? new ActivityOptions(bOptions) : null;
4493 final int launchStackId = (activityOptions != null)
4494 ? activityOptions.getLaunchStackId() : INVALID_STACK_ID;
4496 if (launchStackId == HOME_STACK_ID) {
4497 throw new IllegalArgumentException("startActivityFromRecentsInner: Task "
4498 + taskId + " can't be launch in the home stack.");
4500 task = mStackSupervisor.anyTaskForIdLocked(taskId, RESTORE_FROM_RECENTS, launchStackId);
4502 throw new IllegalArgumentException(
4503 "startActivityFromRecentsInner: Task " + taskId + " not found.");
4506 if (launchStackId != INVALID_STACK_ID) {
4507 if (launchStackId == DOCKED_STACK_ID && activityOptions != null) {
4508 mWindowManager.setDockedStackCreateState(
4509 activityOptions.getDockCreateMode(), null /* initialBounds */);
4511 if (task.stack.mStackId != launchStackId) {
4512 mStackSupervisor.moveTaskToStackLocked(
4513 taskId, launchStackId, ON_TOP, FORCE_FOCUS, "startActivityFromRecents",
4518 // If the user must confirm credentials (e.g. when first launching a work app and the
4519 // Work Challenge is present) let startActivityInPackage handle the intercepting.
4520 if (!mUserController.shouldConfirmCredentials(task.userId)
4521 && task.getRootActivity() != null) {
4522 moveTaskToFrontLocked(task.taskId, 0, bOptions);
4523 return ActivityManager.START_TASK_TO_FRONT;
4525 callingUid = task.mCallingUid;
4526 callingPackage = task.mCallingPackage;
4527 intent = task.intent;
4528 intent.addFlags(Intent.FLAG_ACTIVITY_LAUNCHED_FROM_HISTORY);
4529 userId = task.userId;
4531 return startActivityInPackage(callingUid, callingPackage, intent, null, null, null, 0, 0,
4532 bOptions, userId, null, task);
4535 final int startActivityInPackage(int uid, String callingPackage,
4536 Intent intent, String resolvedType, IBinder resultTo,
4537 String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4538 IActivityContainer container, TaskRecord inTask) {
4540 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4541 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4543 // TODO: Switch to user app stacks here.
4544 int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4545 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4546 null, null, null, bOptions, false, userId, container, inTask);
4551 public final int startActivities(IApplicationThread caller, String callingPackage,
4552 Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4554 enforceNotIsolatedCaller("startActivities");
4555 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4556 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4557 // TODO: Switch to user app stacks here.
4558 int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4559 resolvedTypes, resultTo, bOptions, userId);
4563 final int startActivitiesInPackage(int uid, String callingPackage,
4564 Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4565 Bundle bOptions, int userId) {
4567 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4568 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4569 // TODO: Switch to user app stacks here.
4570 int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4571 resultTo, bOptions, userId);
4576 public void reportActivityFullyDrawn(IBinder token) {
4577 synchronized (this) {
4578 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4582 r.reportFullyDrawnLocked();
4587 public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4588 synchronized (this) {
4589 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4593 TaskRecord task = r.task;
4594 if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4595 // Fixed screen orientation isn't supported when activities aren't in full screen
4599 final long origId = Binder.clearCallingIdentity();
4600 mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4601 Configuration config = mWindowManager.updateOrientationFromAppTokens(
4602 mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4603 if (config != null) {
4604 r.frozenBeforeDestroy = true;
4605 if (!updateConfigurationLocked(config, r, false)) {
4606 mStackSupervisor.resumeFocusedStackTopActivityLocked();
4609 Binder.restoreCallingIdentity(origId);
4614 public int getRequestedOrientation(IBinder token) {
4615 synchronized (this) {
4616 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4618 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4620 return mWindowManager.getAppOrientation(r.appToken);
4625 * This is the internal entry point for handling Activity.finish().
4627 * @param token The Binder token referencing the Activity we want to finish.
4628 * @param resultCode Result code, if any, from this Activity.
4629 * @param resultData Result data (Intent), if any, from this Activity.
4630 * @param finishTask Whether to finish the task associated with this Activity.
4632 * @return Returns true if the activity successfully finished, or false if it is still running.
4635 public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4637 // Refuse possible leaked file descriptors
4638 if (resultData != null && resultData.hasFileDescriptors() == true) {
4639 throw new IllegalArgumentException("File descriptors passed in Intent");
4642 synchronized(this) {
4643 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4647 // Keep track of the root activity of the task before we finish it
4648 TaskRecord tr = r.task;
4649 ActivityRecord rootR = tr.getRootActivity();
4650 if (rootR == null) {
4651 Slog.w(TAG, "Finishing task with all activities already finished");
4653 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4655 if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4656 mStackSupervisor.isLastLockedTask(tr)) {
4657 Slog.i(TAG, "Not finishing task in lock task mode");
4658 mStackSupervisor.showLockTaskToast();
4661 if (mController != null) {
4662 // Find the first activity that is not finishing.
4663 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4665 // ask watcher if this is allowed
4666 boolean resumeOK = true;
4668 resumeOK = mController.activityResuming(next.packageName);
4669 } catch (RemoteException e) {
4671 Watchdog.getInstance().setActivityController(null);
4675 Slog.i(TAG, "Not finishing activity because controller resumed");
4680 final long origId = Binder.clearCallingIdentity();
4683 final boolean finishWithRootActivity =
4684 finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4685 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4686 || (finishWithRootActivity && r == rootR)) {
4687 // If requested, remove the task that is associated to this activity only if it
4688 // was the root activity in the task. The result code and data is ignored
4689 // because we don't support returning them across task boundaries. Also, to
4690 // keep backwards compatibility we remove the task from recents when finishing
4691 // task with root activity.
4692 res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4694 Slog.i(TAG, "Removing task failed to finish activity");
4697 res = tr.stack.requestFinishActivityLocked(token, resultCode,
4698 resultData, "app-request", true);
4700 Slog.i(TAG, "Failed to finish by app-request");
4705 Binder.restoreCallingIdentity(origId);
4711 public final void finishHeavyWeightApp() {
4712 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4713 != PackageManager.PERMISSION_GRANTED) {
4714 String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4715 + Binder.getCallingPid()
4716 + ", uid=" + Binder.getCallingUid()
4717 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4719 throw new SecurityException(msg);
4722 synchronized(this) {
4723 if (mHeavyWeightProcess == null) {
4727 ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4728 for (int i = 0; i < activities.size(); i++) {
4729 ActivityRecord r = activities.get(i);
4730 if (!r.finishing && r.isInStackLocked()) {
4731 r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4732 null, "finish-heavy", true);
4736 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4737 mHeavyWeightProcess.userId, 0));
4738 mHeavyWeightProcess = null;
4743 public void crashApplication(int uid, int initialPid, String packageName,
4745 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4746 != PackageManager.PERMISSION_GRANTED) {
4747 String msg = "Permission Denial: crashApplication() from pid="
4748 + Binder.getCallingPid()
4749 + ", uid=" + Binder.getCallingUid()
4750 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4752 throw new SecurityException(msg);
4755 synchronized(this) {
4756 mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4761 public final void finishSubActivity(IBinder token, String resultWho,
4763 synchronized(this) {
4764 final long origId = Binder.clearCallingIdentity();
4765 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4767 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4769 Binder.restoreCallingIdentity(origId);
4774 public boolean finishActivityAffinity(IBinder token) {
4775 synchronized(this) {
4776 final long origId = Binder.clearCallingIdentity();
4778 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4783 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4785 final TaskRecord task = r.task;
4786 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4787 mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4788 mStackSupervisor.showLockTaskToast();
4791 return task.stack.finishActivityAffinityLocked(r);
4793 Binder.restoreCallingIdentity(origId);
4799 public void finishVoiceTask(IVoiceInteractionSession session) {
4800 synchronized (this) {
4801 final long origId = Binder.clearCallingIdentity();
4803 // TODO: VI Consider treating local voice interactions and voice tasks
4805 mStackSupervisor.finishVoiceTask(session);
4807 Binder.restoreCallingIdentity(origId);
4814 public boolean releaseActivityInstance(IBinder token) {
4815 synchronized(this) {
4816 final long origId = Binder.clearCallingIdentity();
4818 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4822 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
4824 Binder.restoreCallingIdentity(origId);
4830 public void releaseSomeActivities(IApplicationThread appInt) {
4831 synchronized(this) {
4832 final long origId = Binder.clearCallingIdentity();
4834 ProcessRecord app = getRecordForAppLocked(appInt);
4835 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
4837 Binder.restoreCallingIdentity(origId);
4843 public boolean willActivityBeVisible(IBinder token) {
4844 synchronized(this) {
4845 ActivityStack stack = ActivityRecord.getStackLocked(token);
4846 if (stack != null) {
4847 return stack.willActivityBeVisibleLocked(token);
4854 public void overridePendingTransition(IBinder token, String packageName,
4855 int enterAnim, int exitAnim) {
4856 synchronized(this) {
4857 ActivityRecord self = ActivityRecord.isInStackLocked(token);
4862 final long origId = Binder.clearCallingIdentity();
4864 if (self.state == ActivityState.RESUMED
4865 || self.state == ActivityState.PAUSING) {
4866 mWindowManager.overridePendingAppTransition(packageName,
4867 enterAnim, exitAnim, null);
4870 Binder.restoreCallingIdentity(origId);
4875 * Main function for removing an existing process from the activity manager
4876 * as a result of that process going away. Clears out all connections
4879 private final void handleAppDiedLocked(ProcessRecord app,
4880 boolean restarting, boolean allowRestart) {
4882 boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1);
4883 if (!kept && !restarting) {
4884 removeLruProcessLocked(app);
4886 ProcessList.remove(pid);
4890 if (mProfileProc == app) {
4891 clearProfilerLocked();
4894 // Remove this application's activities from active lists.
4895 boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
4897 app.activities.clear();
4899 if (app.instrumentationClass != null) {
4900 Slog.w(TAG, "Crash of app " + app.processName
4901 + " running instrumentation " + app.instrumentationClass);
4902 Bundle info = new Bundle();
4903 info.putString("shortMsg", "Process crashed.");
4904 finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
4907 if (!restarting && hasVisibleActivities
4908 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
4909 // If there was nothing to resume, and we are not already restarting this process, but
4910 // there is a visible activity that is hosted by the process... then make sure all
4911 // visible activities are running, taking care of restarting this process.
4912 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
4916 private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
4917 IBinder threadBinder = thread.asBinder();
4918 // Find the application record.
4919 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4920 ProcessRecord rec = mLruProcesses.get(i);
4921 if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
4928 final ProcessRecord getRecordForAppLocked(
4929 IApplicationThread thread) {
4930 if (thread == null) {
4934 int appIndex = getLRURecordIndexForAppLocked(thread);
4935 return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
4938 final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
4939 // If there are no longer any background processes running,
4940 // and the app that died was not running instrumentation,
4941 // then tell everyone we are now low on memory.
4942 boolean haveBg = false;
4943 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4944 ProcessRecord rec = mLruProcesses.get(i);
4945 if (rec.thread != null
4946 && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
4953 boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
4955 long now = SystemClock.uptimeMillis();
4956 if (now < (mLastMemUsageReportTime+5*60*1000)) {
4959 mLastMemUsageReportTime = now;
4962 final ArrayList<ProcessMemInfo> memInfos
4963 = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
4964 EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
4965 long now = SystemClock.uptimeMillis();
4966 for (int i=mLruProcesses.size()-1; i>=0; i--) {
4967 ProcessRecord rec = mLruProcesses.get(i);
4968 if (rec == dyingProc || rec.thread == null) {
4972 memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
4973 rec.setProcState, rec.adjType, rec.makeAdjReason()));
4975 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
4976 // The low memory report is overriding any current
4977 // state for a GC request. Make sure to do
4978 // heavy/important/visible/foreground processes first.
4979 if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
4980 rec.lastRequestedGc = 0;
4982 rec.lastRequestedGc = rec.lastLowMemory;
4984 rec.reportLowMemory = true;
4985 rec.lastLowMemory = now;
4986 mProcessesToGc.remove(rec);
4987 addProcessToGcListLocked(rec);
4991 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
4992 mHandler.sendMessage(msg);
4994 scheduleAppGcsLocked();
4998 final void appDiedLocked(ProcessRecord app) {
4999 appDiedLocked(app, app.pid, app.thread, false);
5002 final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5003 boolean fromBinderDied) {
5004 // First check if this ProcessRecord is actually active for the pid.
5005 synchronized (mPidsSelfLocked) {
5006 ProcessRecord curProc = mPidsSelfLocked.get(pid);
5007 if (curProc != app) {
5008 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5013 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5014 synchronized (stats) {
5015 stats.noteProcessDiedLocked(app.info.uid, pid);
5019 if (!fromBinderDied) {
5020 Process.killProcessQuiet(pid);
5022 killProcessGroup(app.info.uid, pid);
5026 // Clean up already done if the process has been re-started.
5027 if (app.pid == pid && app.thread != null &&
5028 app.thread.asBinder() == thread.asBinder()) {
5029 boolean doLowMem = app.instrumentationClass == null;
5030 boolean doOomAdj = doLowMem;
5031 if (!app.killedByAm) {
5032 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5034 mAllowLowerMemLevel = true;
5036 // Note that we always want to do oom adj to update our state with the
5037 // new number of procs.
5038 mAllowLowerMemLevel = false;
5041 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5042 if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5043 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5044 handleAppDiedLocked(app, false, true);
5047 updateOomAdjLocked();
5050 doLowMemReportIfNeededLocked(app);
5052 } else if (app.pid != pid) {
5053 // A new process has already been started.
5054 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5055 + ") has died and restarted (pid " + app.pid + ").");
5056 EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5057 } else if (DEBUG_PROCESSES) {
5058 Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5059 + thread.asBinder());
5064 * If a stack trace dump file is configured, dump process stack traces.
5065 * @param clearTraces causes the dump file to be erased prior to the new
5066 * traces being written, if true; when false, the new traces will be
5067 * appended to any existing file content.
5068 * @param firstPids of dalvik VM processes to dump stack traces for first
5069 * @param lastPids of dalvik VM processes to dump stack traces for last
5070 * @param nativeProcs optional list of native process names to dump stack crawls
5071 * @return file containing stack traces, or null if no dump file is configured
5073 public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5074 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5075 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5076 if (tracesPath == null || tracesPath.length() == 0) {
5080 File tracesFile = new File(tracesPath);
5082 if (clearTraces && tracesFile.exists()) tracesFile.delete();
5083 tracesFile.createNewFile();
5084 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5085 } catch (IOException e) {
5086 Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5090 dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5094 private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5095 ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5096 // Use a FileObserver to detect when traces finish writing.
5097 // The order of traces is considered important to maintain for legibility.
5098 FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5100 public synchronized void onEvent(int event, String path) { notify(); }
5104 observer.startWatching();
5106 // First collect all of the stacks of the most important pids.
5107 if (firstPids != null) {
5109 int num = firstPids.size();
5110 for (int i = 0; i < num; i++) {
5111 synchronized (observer) {
5112 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5113 + firstPids.get(i));
5114 final long sime = SystemClock.elapsedRealtime();
5115 Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5116 observer.wait(1000); // Wait for write-close, give up after 1 sec
5117 if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5118 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5121 } catch (InterruptedException e) {
5126 // Next collect the stacks of the native pids
5127 if (nativeProcs != null) {
5128 int[] pids = Process.getPidsForCommands(nativeProcs);
5130 for (int pid : pids) {
5131 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5132 final long sime = SystemClock.elapsedRealtime();
5133 Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5134 if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5135 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5140 // Lastly, measure CPU usage.
5141 if (processCpuTracker != null) {
5142 processCpuTracker.init();
5144 processCpuTracker.update();
5146 synchronized (processCpuTracker) {
5147 processCpuTracker.wait(500); // measure over 1/2 second.
5149 } catch (InterruptedException e) {
5151 processCpuTracker.update();
5153 // We'll take the stack crawls of just the top apps using CPU.
5154 final int N = processCpuTracker.countWorkingStats();
5156 for (int i=0; i<N && numProcs<5; i++) {
5157 ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5158 if (lastPids.indexOfKey(stats.pid) >= 0) {
5161 synchronized (observer) {
5162 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5164 final long stime = SystemClock.elapsedRealtime();
5165 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5166 observer.wait(1000); // Wait for write-close, give up after 1 sec
5167 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5168 + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5170 } catch (InterruptedException e) {
5173 } else if (DEBUG_ANR) {
5174 Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5180 observer.stopWatching();
5184 final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5185 if (true || IS_USER_BUILD) {
5188 String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5189 if (tracesPath == null || tracesPath.length() == 0) {
5193 StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5194 StrictMode.allowThreadDiskWrites();
5196 final File tracesFile = new File(tracesPath);
5197 final File tracesDir = tracesFile.getParentFile();
5198 final File tracesTmp = new File(tracesDir, "__tmp__");
5200 if (tracesFile.exists()) {
5202 tracesFile.renameTo(tracesTmp);
5204 StringBuilder sb = new StringBuilder();
5205 Time tobj = new Time();
5206 tobj.set(System.currentTimeMillis());
5207 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5209 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5210 sb.append(" since ");
5212 FileOutputStream fos = new FileOutputStream(tracesFile);
5213 fos.write(sb.toString().getBytes());
5215 fos.write("\n*** No application process!".getBytes());
5218 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5219 } catch (IOException e) {
5220 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5225 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5226 firstPids.add(app.pid);
5227 dumpStackTraces(tracesPath, firstPids, null, null, null);
5230 File lastTracesFile = null;
5231 File curTracesFile = null;
5232 for (int i=9; i>=0; i--) {
5233 String name = String.format(Locale.US, "slow%02d.txt", i);
5234 curTracesFile = new File(tracesDir, name);
5235 if (curTracesFile.exists()) {
5236 if (lastTracesFile != null) {
5237 curTracesFile.renameTo(lastTracesFile);
5239 curTracesFile.delete();
5242 lastTracesFile = curTracesFile;
5244 tracesFile.renameTo(curTracesFile);
5245 if (tracesTmp.exists()) {
5246 tracesTmp.renameTo(tracesFile);
5249 StrictMode.setThreadPolicy(oldPolicy);
5253 final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5254 if (!mLaunchWarningShown) {
5255 mLaunchWarningShown = true;
5256 mUiHandler.post(new Runnable() {
5259 synchronized (ActivityManagerService.this) {
5260 final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5262 mUiHandler.postDelayed(new Runnable() {
5265 synchronized (ActivityManagerService.this) {
5267 mLaunchWarningShown = false;
5278 public boolean clearApplicationUserData(final String packageName,
5279 final IPackageDataObserver observer, int userId) {
5280 enforceNotIsolatedCaller("clearApplicationUserData");
5281 int uid = Binder.getCallingUid();
5282 int pid = Binder.getCallingPid();
5283 userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5284 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5286 final DevicePolicyManagerInternal dpmi = LocalServices
5287 .getService(DevicePolicyManagerInternal.class);
5288 if (dpmi != null && dpmi.hasDeviceOwnerOrProfileOwner(packageName, userId)) {
5289 throw new SecurityException("Cannot clear data for a device owner or a profile owner");
5292 long callingId = Binder.clearCallingIdentity();
5294 IPackageManager pm = AppGlobals.getPackageManager();
5296 synchronized(this) {
5298 pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5299 } catch (RemoteException e) {
5302 Slog.w(TAG, "Invalid packageName: " + packageName);
5303 if (observer != null) {
5305 observer.onRemoveCompleted(packageName, false);
5306 } catch (RemoteException e) {
5307 Slog.i(TAG, "Observer no longer exists.");
5312 if (uid == pkgUid || checkComponentPermission(
5313 android.Manifest.permission.CLEAR_APP_USER_DATA,
5315 == PackageManager.PERMISSION_GRANTED) {
5316 forceStopPackageLocked(packageName, pkgUid, "clear data");
5318 throw new SecurityException("PID " + pid + " does not have permission "
5319 + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5320 + " of package " + packageName);
5323 // Remove all tasks match the cleared application package and user
5324 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5325 final TaskRecord tr = mRecentTasks.get(i);
5326 final String taskPackageName =
5327 tr.getBaseIntent().getComponent().getPackageName();
5328 if (tr.userId != userId) continue;
5329 if (!taskPackageName.equals(packageName)) continue;
5330 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5335 // Clear application user data
5336 pm.clearApplicationUserData(packageName, observer, userId);
5338 synchronized(this) {
5339 // Remove all permissions granted from/to this package
5340 removeUriPermissionsForPackageLocked(packageName, userId, true);
5343 // Remove all zen rules created by this package; revoke it's zen access.
5344 INotificationManager inm = NotificationManager.getService();
5345 inm.removeAutomaticZenRules(packageName);
5346 inm.setNotificationPolicyAccessGranted(packageName, false);
5348 Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5349 Uri.fromParts("package", packageName, null));
5350 intent.putExtra(Intent.EXTRA_UID, pkgUid);
5351 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUid));
5352 broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5353 null, null, 0, null, null, null, null, false, false, userId);
5354 } catch (RemoteException e) {
5357 Binder.restoreCallingIdentity(callingId);
5363 public void killBackgroundProcesses(final String packageName, int userId) {
5364 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5365 != PackageManager.PERMISSION_GRANTED &&
5366 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5367 != PackageManager.PERMISSION_GRANTED) {
5368 String msg = "Permission Denial: killBackgroundProcesses() from pid="
5369 + Binder.getCallingPid()
5370 + ", uid=" + Binder.getCallingUid()
5371 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5373 throw new SecurityException(msg);
5376 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5377 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5378 long callingId = Binder.clearCallingIdentity();
5380 IPackageManager pm = AppGlobals.getPackageManager();
5381 synchronized(this) {
5384 appId = UserHandle.getAppId(
5385 pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5386 } catch (RemoteException e) {
5389 Slog.w(TAG, "Invalid packageName: " + packageName);
5392 killPackageProcessesLocked(packageName, appId, userId,
5393 ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5396 Binder.restoreCallingIdentity(callingId);
5401 public void killAllBackgroundProcesses() {
5402 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5403 != PackageManager.PERMISSION_GRANTED) {
5404 final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5405 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5406 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5408 throw new SecurityException(msg);
5411 final long callingId = Binder.clearCallingIdentity();
5413 synchronized (this) {
5414 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5415 final int NP = mProcessNames.getMap().size();
5416 for (int ip = 0; ip < NP; ip++) {
5417 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5418 final int NA = apps.size();
5419 for (int ia = 0; ia < NA; ia++) {
5420 final ProcessRecord app = apps.valueAt(ia);
5421 if (app.persistent) {
5422 // We don't kill persistent processes.
5427 } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5434 final int N = procs.size();
5435 for (int i = 0; i < N; i++) {
5436 removeProcessLocked(procs.get(i), false, true, "kill all background");
5439 mAllowLowerMemLevel = true;
5441 updateOomAdjLocked();
5442 doLowMemReportIfNeededLocked(null);
5445 Binder.restoreCallingIdentity(callingId);
5450 * Kills all background processes, except those matching any of the
5451 * specified properties.
5453 * @param minTargetSdk the target SDK version at or above which to preserve
5454 * processes, or {@code -1} to ignore the target SDK
5455 * @param maxProcState the process state at or below which to preserve
5456 * processes, or {@code -1} to ignore the process state
5458 private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5459 if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5460 != PackageManager.PERMISSION_GRANTED) {
5461 final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5462 + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5463 + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5465 throw new SecurityException(msg);
5468 final long callingId = Binder.clearCallingIdentity();
5470 synchronized (this) {
5471 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5472 final int NP = mProcessNames.getMap().size();
5473 for (int ip = 0; ip < NP; ip++) {
5474 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5475 final int NA = apps.size();
5476 for (int ia = 0; ia < NA; ia++) {
5477 final ProcessRecord app = apps.valueAt(ia);
5480 } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5481 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5488 final int N = procs.size();
5489 for (int i = 0; i < N; i++) {
5490 removeProcessLocked(procs.get(i), false, true, "kill all background except");
5494 Binder.restoreCallingIdentity(callingId);
5499 public void forceStopPackage(final String packageName, int userId) {
5500 if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5501 != PackageManager.PERMISSION_GRANTED) {
5502 String msg = "Permission Denial: forceStopPackage() from pid="
5503 + Binder.getCallingPid()
5504 + ", uid=" + Binder.getCallingUid()
5505 + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5507 throw new SecurityException(msg);
5509 final int callingPid = Binder.getCallingPid();
5510 userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5511 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5512 long callingId = Binder.clearCallingIdentity();
5514 IPackageManager pm = AppGlobals.getPackageManager();
5515 synchronized(this) {
5516 int[] users = userId == UserHandle.USER_ALL
5517 ? mUserController.getUsers() : new int[] { userId };
5518 for (int user : users) {
5521 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5523 } catch (RemoteException e) {
5526 Slog.w(TAG, "Invalid packageName: " + packageName);
5530 pm.setPackageStoppedState(packageName, true, user);
5531 } catch (RemoteException e) {
5532 } catch (IllegalArgumentException e) {
5533 Slog.w(TAG, "Failed trying to unstop package "
5534 + packageName + ": " + e);
5536 if (mUserController.isUserRunningLocked(user, 0)) {
5537 forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5542 Binder.restoreCallingIdentity(callingId);
5547 public void addPackageDependency(String packageName) {
5548 synchronized (this) {
5549 int callingPid = Binder.getCallingPid();
5550 if (callingPid == Process.myPid()) {
5555 synchronized (mPidsSelfLocked) {
5556 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5559 if (proc.pkgDeps == null) {
5560 proc.pkgDeps = new ArraySet<String>(1);
5562 proc.pkgDeps.add(packageName);
5568 * The pkg name and app id have to be specified.
5571 public void killApplicationWithAppId(String pkg, int appid, String reason) {
5575 // Make sure the uid is valid.
5577 Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5580 int callerUid = Binder.getCallingUid();
5581 // Only the system server can kill an application
5582 if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5583 // Post an aysnc message to kill the application
5584 Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5587 Bundle bundle = new Bundle();
5588 bundle.putString("pkg", pkg);
5589 bundle.putString("reason", reason);
5591 mHandler.sendMessage(msg);
5593 throw new SecurityException(callerUid + " cannot kill pkg: " +
5599 public void closeSystemDialogs(String reason) {
5600 enforceNotIsolatedCaller("closeSystemDialogs");
5602 final int pid = Binder.getCallingPid();
5603 final int uid = Binder.getCallingUid();
5604 final long origId = Binder.clearCallingIdentity();
5606 synchronized (this) {
5607 // Only allow this from foreground processes, so that background
5608 // applications can't abuse it to prevent system UI from being shown.
5609 if (uid >= Process.FIRST_APPLICATION_UID) {
5611 synchronized (mPidsSelfLocked) {
5612 proc = mPidsSelfLocked.get(pid);
5614 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5615 Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5616 + " from background process " + proc);
5620 closeSystemDialogsLocked(reason);
5623 Binder.restoreCallingIdentity(origId);
5627 void closeSystemDialogsLocked(String reason) {
5628 Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5629 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5630 | Intent.FLAG_RECEIVER_FOREGROUND);
5631 if (reason != null) {
5632 intent.putExtra("reason", reason);
5634 mWindowManager.closeSystemDialogs(reason);
5636 mStackSupervisor.closeSystemDialogsLocked();
5638 broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5639 AppOpsManager.OP_NONE, null, false, false,
5640 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5644 public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5645 enforceNotIsolatedCaller("getProcessMemoryInfo");
5646 Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5647 for (int i=pids.length-1; i>=0; i--) {
5650 synchronized (this) {
5651 synchronized (mPidsSelfLocked) {
5652 proc = mPidsSelfLocked.get(pids[i]);
5653 oomAdj = proc != null ? proc.setAdj : 0;
5656 infos[i] = new Debug.MemoryInfo();
5657 Debug.getMemoryInfo(pids[i], infos[i]);
5659 synchronized (this) {
5660 if (proc.thread != null && proc.setAdj == oomAdj) {
5661 // Record this for posterity if the process has been stable.
5662 proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5663 infos[i].getTotalUss(), false, proc.pkgList);
5672 public long[] getProcessPss(int[] pids) {
5673 enforceNotIsolatedCaller("getProcessPss");
5674 long[] pss = new long[pids.length];
5675 for (int i=pids.length-1; i>=0; i--) {
5678 synchronized (this) {
5679 synchronized (mPidsSelfLocked) {
5680 proc = mPidsSelfLocked.get(pids[i]);
5681 oomAdj = proc != null ? proc.setAdj : 0;
5684 long[] tmpUss = new long[1];
5685 pss[i] = Debug.getPss(pids[i], tmpUss, null);
5687 synchronized (this) {
5688 if (proc.thread != null && proc.setAdj == oomAdj) {
5689 // Record this for posterity if the process has been stable.
5690 proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5699 public void killApplicationProcess(String processName, int uid) {
5700 if (processName == null) {
5704 int callerUid = Binder.getCallingUid();
5705 // Only the system server can kill an application
5706 if (callerUid == Process.SYSTEM_UID) {
5707 synchronized (this) {
5708 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5709 if (app != null && app.thread != null) {
5711 app.thread.scheduleSuicide();
5712 } catch (RemoteException e) {
5713 // If the other end already died, then our work here is done.
5716 Slog.w(TAG, "Process/uid not found attempting kill of "
5717 + processName + " / " + uid);
5721 throw new SecurityException(callerUid + " cannot kill app process: " +
5726 private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5727 forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5728 false, true, false, false, UserHandle.getUserId(uid), reason);
5729 Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5730 Uri.fromParts("package", packageName, null));
5731 if (!mProcessesReady) {
5732 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5733 | Intent.FLAG_RECEIVER_FOREGROUND);
5735 intent.putExtra(Intent.EXTRA_UID, uid);
5736 intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5737 broadcastIntentLocked(null, null, intent,
5738 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5739 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5743 private final boolean killPackageProcessesLocked(String packageName, int appId,
5744 int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5745 boolean doit, boolean evenPersistent, String reason) {
5746 ArrayList<ProcessRecord> procs = new ArrayList<>();
5748 // Remove all processes this package may have touched: all with the
5749 // same UID (except for the system or root user), and all whose name
5750 // matches the package name.
5751 final int NP = mProcessNames.getMap().size();
5752 for (int ip=0; ip<NP; ip++) {
5753 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5754 final int NA = apps.size();
5755 for (int ia=0; ia<NA; ia++) {
5756 ProcessRecord app = apps.valueAt(ia);
5757 if (app.persistent && !evenPersistent) {
5758 // we don't kill persistent processes
5768 // Skip process if it doesn't meet our oom adj requirement.
5769 if (app.setAdj < minOomAdj) {
5773 // If no package is specified, we call all processes under the
5775 if (packageName == null) {
5776 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5779 if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5782 // Package has been specified, we want to hit all processes
5783 // that match it. We need to qualify this by the processes
5784 // that are running under the specified app and user ID.
5786 final boolean isDep = app.pkgDeps != null
5787 && app.pkgDeps.contains(packageName);
5788 if (!isDep && UserHandle.getAppId(app.uid) != appId) {
5791 if (userId != UserHandle.USER_ALL && app.userId != userId) {
5794 if (!app.pkgList.containsKey(packageName) && !isDep) {
5799 // Process has passed all conditions, kill it!
5808 int N = procs.size();
5809 for (int i=0; i<N; i++) {
5810 removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
5812 updateOomAdjLocked();
5816 private void cleanupDisabledPackageComponentsLocked(
5817 String packageName, int userId, boolean killProcess, String[] changedClasses) {
5819 Set<String> disabledClasses = null;
5820 boolean packageDisabled = false;
5821 IPackageManager pm = AppGlobals.getPackageManager();
5823 if (changedClasses == null) {
5824 // Nothing changed...
5828 // Determine enable/disable state of the package and its components.
5829 int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5830 for (int i = changedClasses.length - 1; i >= 0; i--) {
5831 final String changedClass = changedClasses[i];
5833 if (changedClass.equals(packageName)) {
5835 // Entire package setting changed
5836 enabled = pm.getApplicationEnabledSetting(packageName,
5837 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5838 } catch (Exception e) {
5839 // No such package/component; probably racing with uninstall. In any
5840 // event it means we have nothing further to do here.
5843 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5844 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
5845 if (packageDisabled) {
5846 // Entire package is disabled.
5847 // No need to continue to check component states.
5848 disabledClasses = null;
5853 enabled = pm.getComponentEnabledSetting(
5854 new ComponentName(packageName, changedClass),
5855 (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
5856 } catch (Exception e) {
5857 // As above, probably racing with uninstall.
5860 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
5861 && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
5862 if (disabledClasses == null) {
5863 disabledClasses = new ArraySet<>(changedClasses.length);
5865 disabledClasses.add(changedClass);
5870 if (!packageDisabled && disabledClasses == null) {
5871 // Nothing to do here...
5875 // Clean-up disabled activities.
5876 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5877 packageName, disabledClasses, true, false, userId) && mBooted) {
5878 mStackSupervisor.resumeFocusedStackTopActivityLocked();
5879 mStackSupervisor.scheduleIdleLocked();
5882 // Clean-up disabled tasks
5883 cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
5885 // Clean-up disabled services.
5886 mServices.bringDownDisabledPackageServicesLocked(
5887 packageName, disabledClasses, userId, false, killProcess, true);
5889 // Clean-up disabled providers.
5890 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5891 mProviderMap.collectPackageProvidersLocked(
5892 packageName, disabledClasses, true, false, userId, providers);
5893 for (int i = providers.size() - 1; i >= 0; i--) {
5894 removeDyingProviderLocked(null, providers.get(i), true);
5897 // Clean-up disabled broadcast receivers.
5898 for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
5899 mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5900 packageName, disabledClasses, userId, true);
5905 final boolean forceStopPackageLocked(String packageName, int appId,
5906 boolean callerWillRestart, boolean purgeCache, boolean doit,
5907 boolean evenPersistent, boolean uninstalling, int userId, String reason) {
5910 if (userId == UserHandle.USER_ALL && packageName == null) {
5911 Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
5914 if (appId < 0 && packageName != null) {
5916 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
5917 .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5918 } catch (RemoteException e) {
5923 if (packageName != null) {
5924 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
5925 + " user=" + userId + ": " + reason);
5927 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
5930 mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
5933 boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
5934 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
5935 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
5937 if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
5938 packageName, null, doit, evenPersistent, userId)) {
5942 didSomething = true;
5945 if (mServices.bringDownDisabledPackageServicesLocked(
5946 packageName, null, userId, evenPersistent, true, doit)) {
5950 didSomething = true;
5953 if (packageName == null) {
5954 // Remove all sticky broadcasts from this user.
5955 mStickyBroadcasts.remove(userId);
5958 ArrayList<ContentProviderRecord> providers = new ArrayList<>();
5959 if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
5960 userId, providers)) {
5964 didSomething = true;
5966 for (i = providers.size() - 1; i >= 0; i--) {
5967 removeDyingProviderLocked(null, providers.get(i), true);
5970 // Remove transient permissions granted from/to this package/user
5971 removeUriPermissionsForPackageLocked(packageName, userId, false);
5974 for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
5975 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
5976 packageName, null, userId, doit);
5980 if (packageName == null || uninstalling) {
5981 // Remove pending intents. For now we only do this when force
5982 // stopping users, because we have some problems when doing this
5983 // for packages -- app widgets are not currently cleaned up for
5984 // such packages, so they can be left with bad pending intents.
5985 if (mIntentSenderRecords.size() > 0) {
5986 Iterator<WeakReference<PendingIntentRecord>> it
5987 = mIntentSenderRecords.values().iterator();
5988 while (it.hasNext()) {
5989 WeakReference<PendingIntentRecord> wpir = it.next();
5994 PendingIntentRecord pir = wpir.get();
5999 if (packageName == null) {
6000 // Stopping user, remove all objects for the user.
6001 if (pir.key.userId != userId) {
6002 // Not the same user, skip it.
6006 if (UserHandle.getAppId(pir.uid) != appId) {
6007 // Different app id, skip it.
6010 if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6011 // Different user, skip it.
6014 if (!pir.key.packageName.equals(packageName)) {
6015 // Different package, skip it.
6022 didSomething = true;
6024 pir.canceled = true;
6025 if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6026 pir.key.activity.pendingResults.remove(pir.ref);
6033 if (purgeCache && packageName != null) {
6034 AttributeCache ac = AttributeCache.instance();
6036 ac.removePackage(packageName);
6040 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6041 mStackSupervisor.scheduleIdleLocked();
6045 return didSomething;
6048 private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6049 ProcessRecord old = mProcessNames.remove(name, uid);
6051 old.uidRecord.numProcs--;
6052 if (old.uidRecord.numProcs == 0) {
6053 // No more processes using this uid, tell clients it is gone.
6054 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6055 "No more processes in " + old.uidRecord);
6056 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6057 mActiveUids.remove(uid);
6058 mBatteryStatsService.noteUidProcessState(uid,
6059 ActivityManager.PROCESS_STATE_NONEXISTENT);
6061 old.uidRecord = null;
6063 mIsolatedProcesses.remove(uid);
6067 private final void addProcessNameLocked(ProcessRecord proc) {
6068 // We shouldn't already have a process under this name, but just in case we
6069 // need to clean up whatever may be there now.
6070 ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6071 if (old == proc && proc.persistent) {
6072 // We are re-adding a persistent process. Whatevs! Just leave it there.
6073 Slog.w(TAG, "Re-adding persistent process " + proc);
6074 } else if (old != null) {
6075 Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6077 UidRecord uidRec = mActiveUids.get(proc.uid);
6078 if (uidRec == null) {
6079 uidRec = new UidRecord(proc.uid);
6080 // This is the first appearance of the uid, report it now!
6081 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6082 "Creating new process uid: " + uidRec);
6083 mActiveUids.put(proc.uid, uidRec);
6084 mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
6085 enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6087 proc.uidRecord = uidRec;
6089 mProcessNames.put(proc.processName, proc.uid, proc);
6090 if (proc.isolated) {
6091 mIsolatedProcesses.put(proc.uid, proc);
6095 boolean removeProcessLocked(ProcessRecord app,
6096 boolean callerWillRestart, boolean allowRestart, String reason) {
6097 final String name = app.processName;
6098 final int uid = app.uid;
6099 if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6100 "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6102 removeProcessNameLocked(name, uid);
6103 if (mHeavyWeightProcess == app) {
6104 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6105 mHeavyWeightProcess.userId, 0));
6106 mHeavyWeightProcess = null;
6108 boolean needRestart = false;
6109 if (app.pid > 0 && app.pid != MY_PID) {
6111 synchronized (mPidsSelfLocked) {
6112 mPidsSelfLocked.remove(pid);
6113 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6115 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6117 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6119 boolean willRestart = false;
6120 if (app.persistent && !app.isolated) {
6121 if (!callerWillRestart) {
6127 app.kill(reason, true);
6128 handleAppDiedLocked(app, willRestart, allowRestart);
6130 removeLruProcessLocked(app);
6131 addAppLocked(app.info, false, null /* ABI override */);
6134 mRemovedProcesses.add(app);
6140 private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6141 cleanupAppInLaunchingProvidersLocked(app, true);
6142 removeProcessLocked(app, false, true, "timeout publishing content providers");
6145 private final void processStartTimedOutLocked(ProcessRecord app) {
6146 final int pid = app.pid;
6147 boolean gone = false;
6148 synchronized (mPidsSelfLocked) {
6149 ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6150 if (knownApp != null && knownApp.thread == null) {
6151 mPidsSelfLocked.remove(pid);
6157 Slog.w(TAG, "Process " + app + " failed to attach");
6158 EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6159 pid, app.uid, app.processName);
6160 removeProcessNameLocked(app.processName, app.uid);
6161 if (mHeavyWeightProcess == app) {
6162 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6163 mHeavyWeightProcess.userId, 0));
6164 mHeavyWeightProcess = null;
6166 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6168 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6170 // Take care of any launching providers waiting for this process.
6171 cleanupAppInLaunchingProvidersLocked(app, true);
6172 // Take care of any services that are waiting for the process.
6173 mServices.processStartTimedOutLocked(app);
6174 app.kill("start timeout", true);
6175 removeLruProcessLocked(app);
6176 if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6177 Slog.w(TAG, "Unattached app died before backup, skipping");
6179 IBackupManager bm = IBackupManager.Stub.asInterface(
6180 ServiceManager.getService(Context.BACKUP_SERVICE));
6181 bm.agentDisconnected(app.info.packageName);
6182 } catch (RemoteException e) {
6183 // Can't happen; the backup manager is local
6186 if (isPendingBroadcastProcessLocked(pid)) {
6187 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6188 skipPendingBroadcastLocked(pid);
6191 Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6195 private final boolean attachApplicationLocked(IApplicationThread thread,
6198 // Find the application record that is being attached... either via
6199 // the pid if we are running in multiple processes, or just pull the
6200 // next app record if we are emulating process with anonymous threads.
6202 if (pid != MY_PID && pid >= 0) {
6203 synchronized (mPidsSelfLocked) {
6204 app = mPidsSelfLocked.get(pid);
6211 Slog.w(TAG, "No pending application record for pid " + pid
6212 + " (IApplicationThread " + thread + "); dropping process");
6213 EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6214 if (pid > 0 && pid != MY_PID) {
6215 Process.killProcessQuiet(pid);
6216 //TODO: killProcessGroup(app.info.uid, pid);
6219 thread.scheduleExit();
6220 } catch (Exception e) {
6221 // Ignore exceptions.
6227 // If this application record is still attached to a previous
6228 // process, clean it up now.
6229 if (app.thread != null) {
6230 handleAppDiedLocked(app, true, true);
6233 // Tell the process all about itself.
6235 if (DEBUG_ALL) Slog.v(
6236 TAG, "Binding process pid " + pid + " to record " + app);
6238 final String processName = app.processName;
6240 AppDeathRecipient adr = new AppDeathRecipient(
6242 thread.asBinder().linkToDeath(adr, 0);
6243 app.deathRecipient = adr;
6244 } catch (RemoteException e) {
6245 app.resetPackageList(mProcessStats);
6246 startProcessLocked(app, "link fail", processName);
6250 EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6252 app.makeActive(thread, mProcessStats);
6253 app.curAdj = app.setAdj = ProcessList.INVALID_ADJ;
6254 app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6255 app.forcingToForeground = null;
6256 updateProcessForegroundLocked(app, false, false);
6257 app.hasShownUi = false;
6258 app.debugging = false;
6260 app.killedByAm = false;
6262 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6264 boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6265 List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6267 if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6268 Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6270 mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6274 Slog.i(TAG, "Launching preboot mode app: " + app);
6277 if (DEBUG_ALL) Slog.v(
6278 TAG, "New app record " + app
6279 + " thread=" + thread.asBinder() + " pid=" + pid);
6281 int testMode = IApplicationThread.DEBUG_OFF;
6282 if (mDebugApp != null && mDebugApp.equals(processName)) {
6283 testMode = mWaitForDebugger
6284 ? IApplicationThread.DEBUG_WAIT
6285 : IApplicationThread.DEBUG_ON;
6286 app.debugging = true;
6287 if (mDebugTransient) {
6288 mDebugApp = mOrigDebugApp;
6289 mWaitForDebugger = mOrigWaitForDebugger;
6292 String profileFile = app.instrumentationProfileFile;
6293 ParcelFileDescriptor profileFd = null;
6294 int samplingInterval = 0;
6295 boolean profileAutoStop = false;
6296 if (mProfileApp != null && mProfileApp.equals(processName)) {
6298 profileFile = mProfileFile;
6299 profileFd = mProfileFd;
6300 samplingInterval = mSamplingInterval;
6301 profileAutoStop = mAutoStopProfiler;
6303 boolean enableTrackAllocation = false;
6304 if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6305 enableTrackAllocation = true;
6306 mTrackAllocationApp = null;
6309 // If the app is being launched for restore or full backup, set it up specially
6310 boolean isRestrictedBackupMode = false;
6311 if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6312 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6313 && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6314 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6315 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6318 notifyPackageUse(app.instrumentationInfo != null
6319 ? app.instrumentationInfo.packageName
6320 : app.info.packageName);
6321 if (app.instrumentationClass != null) {
6322 notifyPackageUse(app.instrumentationClass.getPackageName());
6324 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6325 + processName + " with config " + mConfiguration);
6326 ApplicationInfo appInfo = app.instrumentationInfo != null
6327 ? app.instrumentationInfo : app.info;
6328 app.compat = compatibilityInfoForPackageLocked(appInfo);
6329 if (profileFd != null) {
6330 profileFd = profileFd.dup();
6332 ProfilerInfo profilerInfo = profileFile == null ? null
6333 : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6334 thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6335 profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6336 app.instrumentationUiAutomationConnection, testMode,
6337 mBinderTransactionTrackingEnabled, enableTrackAllocation,
6338 isRestrictedBackupMode || !normalMode, app.persistent,
6339 new Configuration(mConfiguration), app.compat,
6340 getCommonServicesLocked(app.isolated),
6341 mCoreSettingsObserver.getCoreSettingsLocked());
6342 updateLruProcessLocked(app, false, null);
6343 app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6344 } catch (Exception e) {
6345 // todo: Yikes! What should we do? For now we will try to
6346 // start another process, but that could easily get us in
6347 // an infinite loop of restarting processes...
6348 Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6350 app.resetPackageList(mProcessStats);
6351 app.unlinkDeathRecipient();
6352 startProcessLocked(app, "bind fail", processName);
6356 // Remove this record from the list of starting applications.
6357 mPersistentStartingProcesses.remove(app);
6358 if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6359 "Attach application locked removing on hold: " + app);
6360 mProcessesOnHold.remove(app);
6362 boolean badApp = false;
6363 boolean didSomething = false;
6365 // See if the top visible activity is waiting to run in this process...
6368 if (mStackSupervisor.attachApplicationLocked(app)) {
6369 didSomething = true;
6371 } catch (Exception e) {
6372 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6377 // Find any services that should be running in this process...
6380 didSomething |= mServices.attachApplicationLocked(app, processName);
6381 } catch (Exception e) {
6382 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6387 // Check if a next-broadcast receiver is in this process...
6388 if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6390 didSomething |= sendPendingBroadcastsLocked(app);
6391 } catch (Exception e) {
6392 // If the app died trying to launch the receiver we declare it 'bad'
6393 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6398 // Check whether the next backup agent is in this process...
6399 if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6400 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6401 "New app is backup target, launching agent for " + app);
6402 notifyPackageUse(mBackupTarget.appInfo.packageName);
6404 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6405 compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6406 mBackupTarget.backupMode);
6407 } catch (Exception e) {
6408 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6414 app.kill("error during init", true);
6415 handleAppDiedLocked(app, false, true);
6419 if (!didSomething) {
6420 updateOomAdjLocked();
6427 public final void attachApplication(IApplicationThread thread) {
6428 synchronized (this) {
6429 int callingPid = Binder.getCallingPid();
6430 final long origId = Binder.clearCallingIdentity();
6431 attachApplicationLocked(thread, callingPid);
6432 Binder.restoreCallingIdentity(origId);
6437 public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6438 final long origId = Binder.clearCallingIdentity();
6439 synchronized (this) {
6440 ActivityStack stack = ActivityRecord.getStackLocked(token);
6441 if (stack != null) {
6443 mStackSupervisor.activityIdleInternalLocked(token, false, config);
6444 if (stopProfiling) {
6445 if ((mProfileProc == r.app) && (mProfileFd != null)) {
6448 } catch (IOException e) {
6450 clearProfilerLocked();
6455 Binder.restoreCallingIdentity(origId);
6458 void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6459 mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6460 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6463 void enableScreenAfterBoot() {
6464 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6465 SystemClock.uptimeMillis());
6466 mWindowManager.enableScreenAfterBoot();
6468 synchronized (this) {
6469 updateEventDispatchingLocked();
6474 public void showBootMessage(final CharSequence msg, final boolean always) {
6475 if (Binder.getCallingUid() != Process.myUid()) {
6476 // These days only the core system can call this, so apps can't get in
6477 // the way of what we show about running them.
6479 mWindowManager.showBootMessage(msg, always);
6483 public void keyguardWaitingForActivityDrawn() {
6484 enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6485 final long token = Binder.clearCallingIdentity();
6487 synchronized (this) {
6488 if (DEBUG_LOCKSCREEN) logLockScreen("");
6489 mWindowManager.keyguardWaitingForActivityDrawn();
6490 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6491 mLockScreenShown = LOCK_SCREEN_LEAVING;
6492 updateSleepIfNeededLocked();
6496 Binder.restoreCallingIdentity(token);
6501 public void keyguardGoingAway(int flags) {
6502 enforceNotIsolatedCaller("keyguardGoingAway");
6503 final long token = Binder.clearCallingIdentity();
6505 synchronized (this) {
6506 if (DEBUG_LOCKSCREEN) logLockScreen("");
6507 mWindowManager.keyguardGoingAway(flags);
6508 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6509 mLockScreenShown = LOCK_SCREEN_HIDDEN;
6510 updateSleepIfNeededLocked();
6512 // Some stack visibility might change (e.g. docked stack)
6513 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6517 Binder.restoreCallingIdentity(token);
6521 final void finishBooting() {
6522 synchronized (this) {
6523 if (!mBootAnimationComplete) {
6524 mCallFinishBooting = true;
6527 mCallFinishBooting = false;
6530 ArraySet<String> completedIsas = new ArraySet<String>();
6531 for (String abi : Build.SUPPORTED_ABIS) {
6532 Process.establishZygoteConnectionForAbi(abi);
6533 final String instructionSet = VMRuntime.getInstructionSet(abi);
6534 if (!completedIsas.contains(instructionSet)) {
6536 mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6537 } catch (InstallerException e) {
6538 Slog.e(TAG, "Unable to mark boot complete for abi: " + abi, e);
6540 completedIsas.add(instructionSet);
6544 IntentFilter pkgFilter = new IntentFilter();
6545 pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6546 pkgFilter.addDataScheme("package");
6547 mContext.registerReceiver(new BroadcastReceiver() {
6549 public void onReceive(Context context, Intent intent) {
6550 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6552 for (String pkg : pkgs) {
6553 synchronized (ActivityManagerService.this) {
6554 if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6555 0, "query restart")) {
6556 setResultCode(Activity.RESULT_OK);
6565 IntentFilter dumpheapFilter = new IntentFilter();
6566 dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6567 mContext.registerReceiver(new BroadcastReceiver() {
6569 public void onReceive(Context context, Intent intent) {
6570 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6571 mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6573 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6578 mProcessStartLogger.registerListener(mContext);
6580 // Let system services know.
6581 mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6583 synchronized (this) {
6584 // Ensure that any processes we had put on hold are now started
6586 final int NP = mProcessesOnHold.size();
6588 ArrayList<ProcessRecord> procs =
6589 new ArrayList<ProcessRecord>(mProcessesOnHold);
6590 for (int ip=0; ip<NP; ip++) {
6591 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6593 startProcessLocked(procs.get(ip), "on-hold", null);
6597 if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6598 // Start looking for apps that are abusing wake locks.
6599 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6600 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6601 // Tell anyone interested that we are done booting!
6602 SystemProperties.set("sys.boot_completed", "1");
6604 // And trigger dev.bootcomplete if we are not showing encryption progress
6605 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6606 || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6607 SystemProperties.set("dev.bootcomplete", "1");
6609 mUserController.sendBootCompletedLocked(
6610 new IIntentReceiver.Stub() {
6612 public void performReceive(Intent intent, int resultCode,
6613 String data, Bundle extras, boolean ordered,
6614 boolean sticky, int sendingUser) {
6615 synchronized (ActivityManagerService.this) {
6616 requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6621 scheduleStartProfilesLocked();
6627 public void bootAnimationComplete() {
6628 final boolean callFinishBooting;
6629 synchronized (this) {
6630 callFinishBooting = mCallFinishBooting;
6631 mBootAnimationComplete = true;
6633 if (callFinishBooting) {
6634 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6636 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6640 final void ensureBootCompleted() {
6642 boolean enableScreen;
6643 synchronized (this) {
6646 enableScreen = !mBooted;
6651 Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6653 Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6657 enableScreenAfterBoot();
6662 public final void activityResumed(IBinder token) {
6663 final long origId = Binder.clearCallingIdentity();
6664 synchronized(this) {
6665 ActivityStack stack = ActivityRecord.getStackLocked(token);
6666 if (stack != null) {
6667 stack.activityResumedLocked(token);
6670 Binder.restoreCallingIdentity(origId);
6674 public final void activityPaused(IBinder token) {
6675 final long origId = Binder.clearCallingIdentity();
6676 synchronized(this) {
6677 ActivityStack stack = ActivityRecord.getStackLocked(token);
6678 if (stack != null) {
6679 stack.activityPausedLocked(token, false);
6682 Binder.restoreCallingIdentity(origId);
6686 public final void activityStopped(IBinder token, Bundle icicle,
6687 PersistableBundle persistentState, CharSequence description) {
6688 if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6690 // Refuse possible leaked file descriptors
6691 if (icicle != null && icicle.hasFileDescriptors()) {
6692 throw new IllegalArgumentException("File descriptors passed in Bundle");
6695 final long origId = Binder.clearCallingIdentity();
6697 synchronized (this) {
6698 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6700 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6706 Binder.restoreCallingIdentity(origId);
6710 public final void activityDestroyed(IBinder token) {
6711 if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6712 synchronized (this) {
6713 ActivityStack stack = ActivityRecord.getStackLocked(token);
6714 if (stack != null) {
6715 stack.activityDestroyedLocked(token, "activityDestroyed");
6721 public final void activityRelaunched(IBinder token) {
6722 final long origId = Binder.clearCallingIdentity();
6723 synchronized (this) {
6724 mStackSupervisor.activityRelaunchedLocked(token);
6726 Binder.restoreCallingIdentity(origId);
6730 public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6731 int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6732 if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6733 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6734 synchronized (this) {
6735 ActivityRecord record = ActivityRecord.isInStackLocked(token);
6736 if (record == null) {
6737 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6738 + "found for: " + token);
6740 record.setSizeConfigurations(horizontalSizeConfiguration,
6741 verticalSizeConfigurations, smallestSizeConfigurations);
6746 public final void backgroundResourcesReleased(IBinder token) {
6747 final long origId = Binder.clearCallingIdentity();
6749 synchronized (this) {
6750 ActivityStack stack = ActivityRecord.getStackLocked(token);
6751 if (stack != null) {
6752 stack.backgroundResourcesReleased();
6756 Binder.restoreCallingIdentity(origId);
6761 public final void notifyLaunchTaskBehindComplete(IBinder token) {
6762 mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6766 public final void notifyEnterAnimationComplete(IBinder token) {
6767 mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
6771 public String getCallingPackage(IBinder token) {
6772 synchronized (this) {
6773 ActivityRecord r = getCallingRecordLocked(token);
6774 return r != null ? r.info.packageName : null;
6779 public ComponentName getCallingActivity(IBinder token) {
6780 synchronized (this) {
6781 ActivityRecord r = getCallingRecordLocked(token);
6782 return r != null ? r.intent.getComponent() : null;
6786 private ActivityRecord getCallingRecordLocked(IBinder token) {
6787 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6795 public ComponentName getActivityClassForToken(IBinder token) {
6796 synchronized(this) {
6797 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6801 return r.intent.getComponent();
6806 public String getPackageForToken(IBinder token) {
6807 synchronized(this) {
6808 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6812 return r.packageName;
6817 public boolean isRootVoiceInteraction(IBinder token) {
6818 synchronized(this) {
6819 ActivityRecord r = ActivityRecord.isInStackLocked(token);
6823 return r.rootVoiceInteraction;
6828 public IIntentSender getIntentSender(int type,
6829 String packageName, IBinder token, String resultWho,
6830 int requestCode, Intent[] intents, String[] resolvedTypes,
6831 int flags, Bundle bOptions, int userId) {
6832 enforceNotIsolatedCaller("getIntentSender");
6833 // Refuse possible leaked file descriptors
6834 if (intents != null) {
6835 if (intents.length < 1) {
6836 throw new IllegalArgumentException("Intents array length must be >= 1");
6838 for (int i=0; i<intents.length; i++) {
6839 Intent intent = intents[i];
6840 if (intent != null) {
6841 if (intent.hasFileDescriptors()) {
6842 throw new IllegalArgumentException("File descriptors passed in Intent");
6844 if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
6845 (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
6846 throw new IllegalArgumentException(
6847 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
6849 intents[i] = new Intent(intent);
6852 if (resolvedTypes != null && resolvedTypes.length != intents.length) {
6853 throw new IllegalArgumentException(
6854 "Intent array length does not match resolvedTypes length");
6857 if (bOptions != null) {
6858 if (bOptions.hasFileDescriptors()) {
6859 throw new IllegalArgumentException("File descriptors passed in options");
6863 synchronized(this) {
6864 int callingUid = Binder.getCallingUid();
6865 int origUserId = userId;
6866 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
6867 type == ActivityManager.INTENT_SENDER_BROADCAST,
6868 ALLOW_NON_FULL, "getIntentSender", null);
6869 if (origUserId == UserHandle.USER_CURRENT) {
6870 // We don't want to evaluate this until the pending intent is
6871 // actually executed. However, we do want to always do the
6872 // security checking for it above.
6873 userId = UserHandle.USER_CURRENT;
6876 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
6877 final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
6878 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
6879 if (!UserHandle.isSameApp(callingUid, uid)) {
6880 String msg = "Permission Denial: getIntentSender() from pid="
6881 + Binder.getCallingPid()
6882 + ", uid=" + Binder.getCallingUid()
6883 + ", (need uid=" + uid + ")"
6884 + " is not allowed to send as package " + packageName;
6886 throw new SecurityException(msg);
6890 return getIntentSenderLocked(type, packageName, callingUid, userId,
6891 token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
6893 } catch (RemoteException e) {
6894 throw new SecurityException(e);
6899 IIntentSender getIntentSenderLocked(int type, String packageName,
6900 int callingUid, int userId, IBinder token, String resultWho,
6901 int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
6903 if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
6904 ActivityRecord activity = null;
6905 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6906 activity = ActivityRecord.isInStackLocked(token);
6907 if (activity == null) {
6908 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
6911 if (activity.finishing) {
6912 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
6917 // We're going to be splicing together extras before sending, so we're
6918 // okay poking into any contained extras.
6919 if (intents != null) {
6920 for (int i = 0; i < intents.length; i++) {
6921 intents[i].setDefusable(true);
6925 final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
6926 final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
6927 final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
6928 flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
6929 |PendingIntent.FLAG_UPDATE_CURRENT);
6931 PendingIntentRecord.Key key = new PendingIntentRecord.Key(
6932 type, packageName, activity, resultWho,
6933 requestCode, intents, resolvedTypes, flags, bOptions, userId);
6934 WeakReference<PendingIntentRecord> ref;
6935 ref = mIntentSenderRecords.get(key);
6936 PendingIntentRecord rec = ref != null ? ref.get() : null;
6938 if (!cancelCurrent) {
6939 if (updateCurrent) {
6940 if (rec.key.requestIntent != null) {
6941 rec.key.requestIntent.replaceExtras(intents != null ?
6942 intents[intents.length - 1] : null);
6944 if (intents != null) {
6945 intents[intents.length-1] = rec.key.requestIntent;
6946 rec.key.allIntents = intents;
6947 rec.key.allResolvedTypes = resolvedTypes;
6949 rec.key.allIntents = null;
6950 rec.key.allResolvedTypes = null;
6955 rec.canceled = true;
6956 mIntentSenderRecords.remove(key);
6961 rec = new PendingIntentRecord(this, key, callingUid);
6962 mIntentSenderRecords.put(key, rec.ref);
6963 if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
6964 if (activity.pendingResults == null) {
6965 activity.pendingResults
6966 = new HashSet<WeakReference<PendingIntentRecord>>();
6968 activity.pendingResults.add(rec.ref);
6974 public void cancelIntentSender(IIntentSender sender) {
6975 if (!(sender instanceof PendingIntentRecord)) {
6978 synchronized(this) {
6979 PendingIntentRecord rec = (PendingIntentRecord)sender;
6981 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
6982 MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
6983 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
6984 String msg = "Permission Denial: cancelIntentSender() from pid="
6985 + Binder.getCallingPid()
6986 + ", uid=" + Binder.getCallingUid()
6987 + " is not allowed to cancel packges "
6988 + rec.key.packageName;
6990 throw new SecurityException(msg);
6992 } catch (RemoteException e) {
6993 throw new SecurityException(e);
6995 cancelIntentSenderLocked(rec, true);
6999 void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7000 rec.canceled = true;
7001 mIntentSenderRecords.remove(rec.key);
7002 if (cleanActivity && rec.key.activity != null) {
7003 rec.key.activity.pendingResults.remove(rec.ref);
7008 public String getPackageForIntentSender(IIntentSender pendingResult) {
7009 if (!(pendingResult instanceof PendingIntentRecord)) {
7013 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7014 return res.key.packageName;
7015 } catch (ClassCastException e) {
7021 public int getUidForIntentSender(IIntentSender sender) {
7022 if (sender instanceof PendingIntentRecord) {
7024 PendingIntentRecord res = (PendingIntentRecord)sender;
7026 } catch (ClassCastException e) {
7033 public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7034 if (!(pendingResult instanceof PendingIntentRecord)) {
7038 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7039 if (res.key.allIntents == null) {
7042 for (int i=0; i<res.key.allIntents.length; i++) {
7043 Intent intent = res.key.allIntents[i];
7044 if (intent.getPackage() != null && intent.getComponent() != null) {
7049 } catch (ClassCastException e) {
7055 public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7056 if (!(pendingResult instanceof PendingIntentRecord)) {
7060 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7061 if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7065 } catch (ClassCastException e) {
7071 public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7072 enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7073 "getIntentForIntentSender()");
7074 if (!(pendingResult instanceof PendingIntentRecord)) {
7078 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7079 return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7080 } catch (ClassCastException e) {
7086 public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7087 if (!(pendingResult instanceof PendingIntentRecord)) {
7091 PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7092 synchronized (this) {
7093 return getTagForIntentSenderLocked(res, prefix);
7095 } catch (ClassCastException e) {
7100 String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7101 final Intent intent = res.key.requestIntent;
7102 if (intent != null) {
7103 if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7104 || res.lastTagPrefix.equals(prefix))) {
7107 res.lastTagPrefix = prefix;
7108 final StringBuilder sb = new StringBuilder(128);
7109 if (prefix != null) {
7112 if (intent.getAction() != null) {
7113 sb.append(intent.getAction());
7114 } else if (intent.getComponent() != null) {
7115 intent.getComponent().appendShortString(sb);
7119 return res.lastTag = sb.toString();
7125 public void setProcessLimit(int max) {
7126 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7127 "setProcessLimit()");
7128 synchronized (this) {
7129 mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7130 mProcessLimitOverride = max;
7136 public int getProcessLimit() {
7137 synchronized (this) {
7138 return mProcessLimitOverride;
7142 void foregroundTokenDied(ForegroundToken token) {
7143 synchronized (ActivityManagerService.this) {
7144 synchronized (mPidsSelfLocked) {
7146 = mForegroundProcesses.get(token.pid);
7150 mForegroundProcesses.remove(token.pid);
7151 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7155 pr.forcingToForeground = null;
7156 updateProcessForegroundLocked(pr, false, false);
7158 updateOomAdjLocked();
7163 public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7164 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7165 "setProcessForeground()");
7166 synchronized(this) {
7167 boolean changed = false;
7169 synchronized (mPidsSelfLocked) {
7170 ProcessRecord pr = mPidsSelfLocked.get(pid);
7171 if (pr == null && isForeground) {
7172 Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7175 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7176 if (oldToken != null) {
7177 oldToken.token.unlinkToDeath(oldToken, 0);
7178 mForegroundProcesses.remove(pid);
7180 pr.forcingToForeground = null;
7184 if (isForeground && token != null) {
7185 ForegroundToken newToken = new ForegroundToken() {
7187 public void binderDied() {
7188 foregroundTokenDied(this);
7192 newToken.token = token;
7194 token.linkToDeath(newToken, 0);
7195 mForegroundProcesses.put(pid, newToken);
7196 pr.forcingToForeground = token;
7198 } catch (RemoteException e) {
7199 // If the process died while doing this, we will later
7200 // do the cleanup with the process death link.
7206 updateOomAdjLocked();
7212 public boolean isAppForeground(int uid) throws RemoteException {
7213 synchronized (this) {
7214 UidRecord uidRec = mActiveUids.get(uid);
7215 if (uidRec == null || uidRec.idle) {
7218 return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7223 public boolean inMultiWindow(IBinder token) {
7224 final long origId = Binder.clearCallingIdentity();
7226 synchronized(this) {
7227 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7231 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7232 return !r.task.mFullscreen;
7235 Binder.restoreCallingIdentity(origId);
7240 public boolean inPictureInPicture(IBinder token) {
7241 final long origId = Binder.clearCallingIdentity();
7243 synchronized(this) {
7244 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7245 if (stack == null) {
7248 return stack.mStackId == PINNED_STACK_ID;
7251 Binder.restoreCallingIdentity(origId);
7256 public void enterPictureInPicture(IBinder token) {
7257 final long origId = Binder.clearCallingIdentity();
7259 synchronized(this) {
7260 if (!mSupportsPictureInPicture) {
7261 throw new IllegalStateException("enterPictureInPicture: "
7262 + "Device doesn't support picture-in-picture mode.");
7265 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7268 throw new IllegalStateException("enterPictureInPicture: "
7269 + "Can't find activity for token=" + token);
7272 if (!r.supportsPictureInPicture()) {
7273 throw new IllegalArgumentException("enterPictureInPicture: "
7274 + "Picture-In-Picture not supported for r=" + r);
7277 // Use the default launch bounds for pinned stack if it doesn't exist yet.
7278 final Rect bounds = (mStackSupervisor.getStack(PINNED_STACK_ID) == null)
7279 ? mDefaultPinnedStackBounds : null;
7281 mStackSupervisor.moveActivityToPinnedStackLocked(
7282 r, "enterPictureInPicture", bounds);
7285 Binder.restoreCallingIdentity(origId);
7289 // =========================================================
7291 // =========================================================
7293 static class ProcessInfoService extends IProcessInfoService.Stub {
7294 final ActivityManagerService mActivityManagerService;
7295 ProcessInfoService(ActivityManagerService activityManagerService) {
7296 mActivityManagerService = activityManagerService;
7300 public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7301 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7302 /*in*/ pids, /*out*/ states, null);
7306 public void getProcessStatesAndOomScoresFromPids(
7307 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7308 mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7309 /*in*/ pids, /*out*/ states, /*out*/ scores);
7314 * For each PID in the given input array, write the current process state
7315 * for that process into the states array, or -1 to indicate that no
7316 * process with the given PID exists. If scores array is provided, write
7317 * the oom score for the process into the scores array, with INVALID_ADJ
7318 * indicating the PID doesn't exist.
7320 public void getProcessStatesAndOomScoresForPIDs(
7321 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7322 if (scores != null) {
7323 enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7324 "getProcessStatesAndOomScoresForPIDs()");
7328 throw new NullPointerException("pids");
7329 } else if (states == null) {
7330 throw new NullPointerException("states");
7331 } else if (pids.length != states.length) {
7332 throw new IllegalArgumentException("pids and states arrays have different lengths!");
7333 } else if (scores != null && pids.length != scores.length) {
7334 throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7337 synchronized (mPidsSelfLocked) {
7338 for (int i = 0; i < pids.length; i++) {
7339 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7340 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7342 if (scores != null) {
7343 scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7349 // =========================================================
7351 // =========================================================
7353 static class PermissionController extends IPermissionController.Stub {
7354 ActivityManagerService mActivityManagerService;
7355 PermissionController(ActivityManagerService activityManagerService) {
7356 mActivityManagerService = activityManagerService;
7360 public boolean checkPermission(String permission, int pid, int uid) {
7361 return mActivityManagerService.checkPermission(permission, pid,
7362 uid) == PackageManager.PERMISSION_GRANTED;
7366 public String[] getPackagesForUid(int uid) {
7367 return mActivityManagerService.mContext.getPackageManager()
7368 .getPackagesForUid(uid);
7372 public boolean isRuntimePermission(String permission) {
7374 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7375 .getPermissionInfo(permission, 0);
7376 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7377 } catch (NameNotFoundException nnfe) {
7378 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7384 class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7386 public int checkComponentPermission(String permission, int pid, int uid,
7387 int owningUid, boolean exported) {
7388 return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7389 owningUid, exported);
7393 public Object getAMSLock() {
7394 return ActivityManagerService.this;
7399 * This can be called with or without the global lock held.
7401 int checkComponentPermission(String permission, int pid, int uid,
7402 int owningUid, boolean exported) {
7403 if (pid == MY_PID) {
7404 return PackageManager.PERMISSION_GRANTED;
7406 return ActivityManager.checkComponentPermission(permission, uid,
7407 owningUid, exported);
7411 * As the only public entry point for permissions checking, this method
7412 * can enforce the semantic that requesting a check on a null global
7413 * permission is automatically denied. (Internally a null permission
7414 * string is used when calling {@link #checkComponentPermission} in cases
7415 * when only uid-based security is needed.)
7417 * This can be called with or without the global lock held.
7420 public int checkPermission(String permission, int pid, int uid) {
7421 if (permission == null) {
7422 return PackageManager.PERMISSION_DENIED;
7424 return checkComponentPermission(permission, pid, uid, -1, true);
7428 public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7429 if (permission == null) {
7430 return PackageManager.PERMISSION_DENIED;
7433 // We might be performing an operation on behalf of an indirect binder
7434 // invocation, e.g. via {@link #openContentUri}. Check and adjust the
7435 // client identity accordingly before proceeding.
7436 Identity tlsIdentity = sCallerIdentity.get();
7437 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7438 Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7439 + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7440 uid = tlsIdentity.uid;
7441 pid = tlsIdentity.pid;
7444 return checkComponentPermission(permission, pid, uid, -1, true);
7448 * Binder IPC calls go through the public entry point.
7449 * This can be called with or without the global lock held.
7451 int checkCallingPermission(String permission) {
7452 return checkPermission(permission,
7453 Binder.getCallingPid(),
7454 UserHandle.getAppId(Binder.getCallingUid()));
7458 * This can be called with or without the global lock held.
7460 void enforceCallingPermission(String permission, String func) {
7461 if (checkCallingPermission(permission)
7462 == PackageManager.PERMISSION_GRANTED) {
7466 String msg = "Permission Denial: " + func + " from pid="
7467 + Binder.getCallingPid()
7468 + ", uid=" + Binder.getCallingUid()
7469 + " requires " + permission;
7471 throw new SecurityException(msg);
7475 * Determine if UID is holding permissions required to access {@link Uri} in
7476 * the given {@link ProviderInfo}. Final permission checking is always done
7477 * in {@link ContentProvider}.
7479 private final boolean checkHoldingPermissionsLocked(
7480 IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7481 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7482 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7483 if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7484 if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7485 != PERMISSION_GRANTED) {
7489 return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7492 private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7493 GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7494 if (pi.applicationInfo.uid == uid) {
7496 } else if (!pi.exported) {
7500 boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7501 boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7503 // check if target holds top-level <provider> permissions
7504 if (!readMet && pi.readPermission != null && considerUidPermissions
7505 && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7508 if (!writeMet && pi.writePermission != null && considerUidPermissions
7509 && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7513 // track if unprotected read/write is allowed; any denied
7514 // <path-permission> below removes this ability
7515 boolean allowDefaultRead = pi.readPermission == null;
7516 boolean allowDefaultWrite = pi.writePermission == null;
7518 // check if target holds any <path-permission> that match uri
7519 final PathPermission[] pps = pi.pathPermissions;
7521 final String path = grantUri.uri.getPath();
7523 while (i > 0 && (!readMet || !writeMet)) {
7525 PathPermission pp = pps[i];
7526 if (pp.match(path)) {
7528 final String pprperm = pp.getReadPermission();
7529 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7530 "Checking read perm for " + pprperm + " for " + pp.getPath()
7531 + ": match=" + pp.match(path)
7532 + " check=" + pm.checkUidPermission(pprperm, uid));
7533 if (pprperm != null) {
7534 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7535 == PERMISSION_GRANTED) {
7538 allowDefaultRead = false;
7543 final String ppwperm = pp.getWritePermission();
7544 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7545 "Checking write perm " + ppwperm + " for " + pp.getPath()
7546 + ": match=" + pp.match(path)
7547 + " check=" + pm.checkUidPermission(ppwperm, uid));
7548 if (ppwperm != null) {
7549 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7550 == PERMISSION_GRANTED) {
7553 allowDefaultWrite = false;
7561 // grant unprotected <provider> read/write, if not blocked by
7562 // <path-permission> above
7563 if (allowDefaultRead) readMet = true;
7564 if (allowDefaultWrite) writeMet = true;
7566 } catch (RemoteException e) {
7570 return readMet && writeMet;
7573 public int getAppStartMode(int uid, String packageName) {
7574 synchronized (this) {
7575 return checkAllowBackgroundLocked(uid, packageName, -1);
7579 int checkAllowBackgroundLocked(int uid, String packageName, int callingPid) {
7580 UidRecord uidRec = mActiveUids.get(uid);
7581 if (!mLenientBackgroundCheck) {
7583 || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7584 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7585 packageName) != AppOpsManager.MODE_ALLOWED) {
7586 return ActivityManager.APP_START_MODE_DELAYED;
7590 } else if (uidRec == null || uidRec.idle) {
7591 if (callingPid >= 0) {
7593 synchronized (mPidsSelfLocked) {
7594 proc = mPidsSelfLocked.get(callingPid);
7596 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7597 // Whoever is instigating this is in the foreground, so we will allow it
7599 return ActivityManager.APP_START_MODE_NORMAL;
7602 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7603 != AppOpsManager.MODE_ALLOWED) {
7604 return ActivityManager.APP_START_MODE_DELAYED;
7607 return ActivityManager.APP_START_MODE_NORMAL;
7610 private ProviderInfo getProviderInfoLocked(String authority, int userHandle) {
7611 ProviderInfo pi = null;
7612 ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7617 pi = AppGlobals.getPackageManager().resolveContentProvider(
7618 authority, PackageManager.GET_URI_PERMISSION_PATTERNS, userHandle);
7619 } catch (RemoteException ex) {
7625 private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7626 final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7627 if (targetUris != null) {
7628 return targetUris.get(grantUri);
7633 private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7634 String targetPkg, int targetUid, GrantUri grantUri) {
7635 ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7636 if (targetUris == null) {
7637 targetUris = Maps.newArrayMap();
7638 mGrantedUriPermissions.put(targetUid, targetUris);
7641 UriPermission perm = targetUris.get(grantUri);
7643 perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7644 targetUris.put(grantUri, perm);
7650 private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7651 final int modeFlags) {
7652 final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7653 final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7654 : UriPermission.STRENGTH_OWNED;
7656 // Root gets to do everything.
7661 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7662 if (perms == null) return false;
7664 // First look for exact match
7665 final UriPermission exactPerm = perms.get(grantUri);
7666 if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7670 // No exact match, look for prefixes
7671 final int N = perms.size();
7672 for (int i = 0; i < N; i++) {
7673 final UriPermission perm = perms.valueAt(i);
7674 if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7675 && perm.getStrength(modeFlags) >= minStrength) {
7684 * @param uri This uri must NOT contain an embedded userId.
7685 * @param userId The userId in which the uri is to be resolved.
7688 public int checkUriPermission(Uri uri, int pid, int uid,
7689 final int modeFlags, int userId, IBinder callerToken) {
7690 enforceNotIsolatedCaller("checkUriPermission");
7692 // Another redirected-binder-call permissions check as in
7693 // {@link checkPermissionWithToken}.
7694 Identity tlsIdentity = sCallerIdentity.get();
7695 if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7696 uid = tlsIdentity.uid;
7697 pid = tlsIdentity.pid;
7700 // Our own process gets to do everything.
7701 if (pid == MY_PID) {
7702 return PackageManager.PERMISSION_GRANTED;
7704 synchronized (this) {
7705 return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
7706 ? PackageManager.PERMISSION_GRANTED
7707 : PackageManager.PERMISSION_DENIED;
7712 * Check if the targetPkg can be granted permission to access uri by
7713 * the callingUid using the given modeFlags. Throws a security exception
7714 * if callingUid is not allowed to do this. Returns the uid of the target
7715 * if the URI permission grant should be performed; returns -1 if it is not
7716 * needed (for example targetPkg already has permission to access the URI).
7717 * If you already know the uid of the target, you can supply it in
7718 * lastTargetUid else set that to -1.
7720 int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7721 final int modeFlags, int lastTargetUid) {
7722 if (!Intent.isAccessUriMode(modeFlags)) {
7726 if (targetPkg != null) {
7727 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7728 "Checking grant " + targetPkg + " permission to " + grantUri);
7731 final IPackageManager pm = AppGlobals.getPackageManager();
7733 // If this is not a content: uri, we can't do anything with it.
7734 if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
7735 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7736 "Can't grant URI permission for non-content URI: " + grantUri);
7740 final String authority = grantUri.uri.getAuthority();
7741 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7743 Slog.w(TAG, "No content provider found for permission check: " +
7744 grantUri.uri.toSafeString());
7748 int targetUid = lastTargetUid;
7749 if (targetUid < 0 && targetPkg != null) {
7751 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7752 UserHandle.getUserId(callingUid));
7753 if (targetUid < 0) {
7754 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7755 "Can't grant URI permission no uid for: " + targetPkg);
7758 } catch (RemoteException ex) {
7763 if (targetUid >= 0) {
7764 // First... does the target actually need this permission?
7765 if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
7766 // No need to grant the target this permission.
7767 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7768 "Target " + targetPkg + " already has full permission to " + grantUri);
7772 // First... there is no target package, so can anyone access it?
7773 boolean allowed = pi.exported;
7774 if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
7775 if (pi.readPermission != null) {
7779 if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
7780 if (pi.writePermission != null) {
7789 /* There is a special cross user grant if:
7790 * - The target is on another user.
7791 * - Apps on the current user can access the uri without any uid permissions.
7792 * In this case, we grant a uri permission, even if the ContentProvider does not normally
7793 * grant uri permissions.
7795 boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
7796 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
7797 modeFlags, false /*without considering the uid permissions*/);
7799 // Second... is the provider allowing granting of URI permissions?
7800 if (!specialCrossUserGrant) {
7801 if (!pi.grantUriPermissions) {
7802 throw new SecurityException("Provider " + pi.packageName
7804 + " does not allow granting of Uri permissions (uri "
7807 if (pi.uriPermissionPatterns != null) {
7808 final int N = pi.uriPermissionPatterns.length;
7809 boolean allowed = false;
7810 for (int i=0; i<N; i++) {
7811 if (pi.uriPermissionPatterns[i] != null
7812 && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
7818 throw new SecurityException("Provider " + pi.packageName
7820 + " does not allow granting of permission to path of Uri "
7826 // Third... does the caller itself have permission to access
7828 if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
7829 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
7830 // Require they hold a strong enough Uri permission
7831 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
7832 throw new SecurityException("Uid " + callingUid
7833 + " does not have permission to uri " + grantUri);
7841 * @param uri This uri must NOT contain an embedded userId.
7842 * @param userId The userId in which the uri is to be resolved.
7845 public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
7846 final int modeFlags, int userId) {
7847 enforceNotIsolatedCaller("checkGrantUriPermission");
7848 synchronized(this) {
7849 return checkGrantUriPermissionLocked(callingUid, targetPkg,
7850 new GrantUri(userId, uri, false), modeFlags, -1);
7854 void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
7855 final int modeFlags, UriPermissionOwner owner) {
7856 if (!Intent.isAccessUriMode(modeFlags)) {
7860 // So here we are: the caller has the assumed permission
7861 // to the uri, and the target doesn't. Let's now give this to
7864 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7865 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
7867 final String authority = grantUri.uri.getAuthority();
7868 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
7870 Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
7874 if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
7875 grantUri.prefix = true;
7877 final UriPermission perm = findOrCreateUriPermissionLocked(
7878 pi.packageName, targetPkg, targetUid, grantUri);
7879 perm.grantModes(modeFlags, owner);
7882 void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
7883 final int modeFlags, UriPermissionOwner owner, int targetUserId) {
7884 if (targetPkg == null) {
7885 throw new NullPointerException("targetPkg");
7888 final IPackageManager pm = AppGlobals.getPackageManager();
7890 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
7891 } catch (RemoteException ex) {
7895 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
7897 if (targetUid < 0) {
7901 grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
7905 static class NeededUriGrants extends ArrayList<GrantUri> {
7906 final String targetPkg;
7907 final int targetUid;
7910 NeededUriGrants(String targetPkg, int targetUid, int flags) {
7911 this.targetPkg = targetPkg;
7912 this.targetUid = targetUid;
7918 * Like checkGrantUriPermissionLocked, but takes an Intent.
7920 NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
7921 String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
7922 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7923 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
7924 + " clip=" + (intent != null ? intent.getClipData() : null)
7925 + " from " + intent + "; flags=0x"
7926 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
7928 if (targetPkg == null) {
7929 throw new NullPointerException("targetPkg");
7932 if (intent == null) {
7935 Uri data = intent.getData();
7936 ClipData clip = intent.getClipData();
7937 if (data == null && clip == null) {
7940 // Default userId for uris in the intent (if they don't specify it themselves)
7941 int contentUserHint = intent.getContentUserHint();
7942 if (contentUserHint == UserHandle.USER_CURRENT) {
7943 contentUserHint = UserHandle.getUserId(callingUid);
7945 final IPackageManager pm = AppGlobals.getPackageManager();
7947 if (needed != null) {
7948 targetUid = needed.targetUid;
7951 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
7953 } catch (RemoteException ex) {
7956 if (targetUid < 0) {
7957 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7958 "Can't grant URI permission no uid for: " + targetPkg
7959 + " on user " + targetUserId);
7964 GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
7965 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7967 if (targetUid > 0) {
7968 if (needed == null) {
7969 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7971 needed.add(grantUri);
7975 for (int i=0; i<clip.getItemCount(); i++) {
7976 Uri uri = clip.getItemAt(i).getUri();
7978 GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
7979 targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
7981 if (targetUid > 0) {
7982 if (needed == null) {
7983 needed = new NeededUriGrants(targetPkg, targetUid, mode);
7985 needed.add(grantUri);
7988 Intent clipIntent = clip.getItemAt(i).getIntent();
7989 if (clipIntent != null) {
7990 NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
7991 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
7992 if (newNeeded != null) {
8004 * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8006 void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8007 UriPermissionOwner owner) {
8008 if (needed != null) {
8009 for (int i=0; i<needed.size(); i++) {
8010 GrantUri grantUri = needed.get(i);
8011 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8012 grantUri, needed.flags, owner);
8017 void grantUriPermissionFromIntentLocked(int callingUid,
8018 String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8019 NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8020 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8021 if (needed == null) {
8025 grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8029 * @param uri This uri must NOT contain an embedded userId.
8030 * @param userId The userId in which the uri is to be resolved.
8033 public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8034 final int modeFlags, int userId) {
8035 enforceNotIsolatedCaller("grantUriPermission");
8036 GrantUri grantUri = new GrantUri(userId, uri, false);
8037 synchronized(this) {
8038 final ProcessRecord r = getRecordForAppLocked(caller);
8040 throw new SecurityException("Unable to find app for caller "
8042 + " when granting permission to uri " + grantUri);
8044 if (targetPkg == null) {
8045 throw new IllegalArgumentException("null target");
8047 if (grantUri == null) {
8048 throw new IllegalArgumentException("null uri");
8051 Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8052 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8053 | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8054 | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8056 grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8057 UserHandle.getUserId(r.uid));
8061 void removeUriPermissionIfNeededLocked(UriPermission perm) {
8062 if (perm.modeFlags == 0) {
8063 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8065 if (perms != null) {
8066 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8067 "Removing " + perm.targetUid + " permission to " + perm.uri);
8069 perms.remove(perm.uri);
8070 if (perms.isEmpty()) {
8071 mGrantedUriPermissions.remove(perm.targetUid);
8077 private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8078 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079 "Revoking all granted permissions to " + grantUri);
8081 final IPackageManager pm = AppGlobals.getPackageManager();
8082 final String authority = grantUri.uri.getAuthority();
8083 final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId);
8085 Slog.w(TAG, "No content provider found for permission revoke: "
8086 + grantUri.toSafeString());
8090 // Does the caller have this permission on the URI?
8091 if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8092 // If they don't have direct access to the URI, then revoke any
8093 // ownerless URI permissions that have been granted to them.
8094 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8095 if (perms != null) {
8096 boolean persistChanged = false;
8097 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8098 final UriPermission perm = it.next();
8099 if (perm.uri.sourceUserId == grantUri.sourceUserId
8100 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8101 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8102 "Revoking non-owned " + perm.targetUid
8103 + " permission to " + perm.uri);
8104 persistChanged |= perm.revokeModes(
8105 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8106 if (perm.modeFlags == 0) {
8111 if (perms.isEmpty()) {
8112 mGrantedUriPermissions.remove(callingUid);
8114 if (persistChanged) {
8115 schedulePersistUriGrants();
8121 boolean persistChanged = false;
8123 // Go through all of the permissions and remove any that match.
8124 int N = mGrantedUriPermissions.size();
8125 for (int i = 0; i < N; i++) {
8126 final int targetUid = mGrantedUriPermissions.keyAt(i);
8127 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8129 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8130 final UriPermission perm = it.next();
8131 if (perm.uri.sourceUserId == grantUri.sourceUserId
8132 && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8133 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8134 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8135 persistChanged |= perm.revokeModes(
8136 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8137 if (perm.modeFlags == 0) {
8143 if (perms.isEmpty()) {
8144 mGrantedUriPermissions.remove(targetUid);
8150 if (persistChanged) {
8151 schedulePersistUriGrants();
8156 * @param uri This uri must NOT contain an embedded userId.
8157 * @param userId The userId in which the uri is to be resolved.
8160 public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8162 enforceNotIsolatedCaller("revokeUriPermission");
8163 synchronized(this) {
8164 final ProcessRecord r = getRecordForAppLocked(caller);
8166 throw new SecurityException("Unable to find app for caller "
8168 + " when revoking permission to uri " + uri);
8171 Slog.w(TAG, "revokeUriPermission: null uri");
8175 if (!Intent.isAccessUriMode(modeFlags)) {
8179 final String authority = uri.getAuthority();
8180 final ProviderInfo pi = getProviderInfoLocked(authority, userId);
8182 Slog.w(TAG, "No content provider found for permission revoke: "
8183 + uri.toSafeString());
8187 revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8192 * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8195 * @param packageName Package name to match, or {@code null} to apply to all
8197 * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8199 * @param persistable If persistable grants should be removed.
8201 private void removeUriPermissionsForPackageLocked(
8202 String packageName, int userHandle, boolean persistable) {
8203 if (userHandle == UserHandle.USER_ALL && packageName == null) {
8204 throw new IllegalArgumentException("Must narrow by either package or user");
8207 boolean persistChanged = false;
8209 int N = mGrantedUriPermissions.size();
8210 for (int i = 0; i < N; i++) {
8211 final int targetUid = mGrantedUriPermissions.keyAt(i);
8212 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8214 // Only inspect grants matching user
8215 if (userHandle == UserHandle.USER_ALL
8216 || userHandle == UserHandle.getUserId(targetUid)) {
8217 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8218 final UriPermission perm = it.next();
8220 // Only inspect grants matching package
8221 if (packageName == null || perm.sourcePkg.equals(packageName)
8222 || perm.targetPkg.equals(packageName)) {
8223 persistChanged |= perm.revokeModes(persistable
8224 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8226 // Only remove when no modes remain; any persisted grants
8227 // will keep this alive.
8228 if (perm.modeFlags == 0) {
8234 if (perms.isEmpty()) {
8235 mGrantedUriPermissions.remove(targetUid);
8242 if (persistChanged) {
8243 schedulePersistUriGrants();
8248 public IBinder newUriPermissionOwner(String name) {
8249 enforceNotIsolatedCaller("newUriPermissionOwner");
8250 synchronized(this) {
8251 UriPermissionOwner owner = new UriPermissionOwner(this, name);
8252 return owner.getExternalTokenLocked();
8257 public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8258 enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8259 synchronized(this) {
8260 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8262 throw new IllegalArgumentException("Activity does not exist; token="
8265 return r.getUriPermissionsLocked().getExternalTokenLocked();
8269 * @param uri This uri must NOT contain an embedded userId.
8270 * @param sourceUserId The userId in which the uri is to be resolved.
8271 * @param targetUserId The userId of the app that receives the grant.
8274 public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8275 final int modeFlags, int sourceUserId, int targetUserId) {
8276 targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8277 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8278 "grantUriPermissionFromOwner", null);
8279 synchronized(this) {
8280 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8281 if (owner == null) {
8282 throw new IllegalArgumentException("Unknown owner: " + token);
8284 if (fromUid != Binder.getCallingUid()) {
8285 if (Binder.getCallingUid() != Process.myUid()) {
8286 // Only system code can grant URI permissions on behalf
8288 throw new SecurityException("nice try");
8291 if (targetPkg == null) {
8292 throw new IllegalArgumentException("null target");
8295 throw new IllegalArgumentException("null uri");
8298 grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8299 modeFlags, owner, targetUserId);
8304 * @param uri This uri must NOT contain an embedded userId.
8305 * @param userId The userId in which the uri is to be resolved.
8308 public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8309 synchronized(this) {
8310 UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8311 if (owner == null) {
8312 throw new IllegalArgumentException("Unknown owner: " + token);
8316 owner.removeUriPermissionsLocked(mode);
8318 owner.removeUriPermissionLocked(new GrantUri(userId, uri, false), mode);
8323 private void schedulePersistUriGrants() {
8324 if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8325 mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8326 10 * DateUtils.SECOND_IN_MILLIS);
8330 private void writeGrantedUriPermissions() {
8331 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8333 // Snapshot permissions so we can persist without lock
8334 ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8335 synchronized (this) {
8336 final int size = mGrantedUriPermissions.size();
8337 for (int i = 0; i < size; i++) {
8338 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8339 for (UriPermission perm : perms.values()) {
8340 if (perm.persistedModeFlags != 0) {
8341 persist.add(perm.snapshot());
8347 FileOutputStream fos = null;
8349 fos = mGrantFile.startWrite();
8351 XmlSerializer out = new FastXmlSerializer();
8352 out.setOutput(fos, StandardCharsets.UTF_8.name());
8353 out.startDocument(null, true);
8354 out.startTag(null, TAG_URI_GRANTS);
8355 for (UriPermission.Snapshot perm : persist) {
8356 out.startTag(null, TAG_URI_GRANT);
8357 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8358 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8359 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8360 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8361 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8362 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8363 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8364 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8365 out.endTag(null, TAG_URI_GRANT);
8367 out.endTag(null, TAG_URI_GRANTS);
8370 mGrantFile.finishWrite(fos);
8371 } catch (IOException e) {
8373 mGrantFile.failWrite(fos);
8378 private void readGrantedUriPermissionsLocked() {
8379 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8381 final long now = System.currentTimeMillis();
8383 FileInputStream fis = null;
8385 fis = mGrantFile.openRead();
8386 final XmlPullParser in = Xml.newPullParser();
8387 in.setInput(fis, StandardCharsets.UTF_8.name());
8390 while ((type = in.next()) != END_DOCUMENT) {
8391 final String tag = in.getName();
8392 if (type == START_TAG) {
8393 if (TAG_URI_GRANT.equals(tag)) {
8394 final int sourceUserId;
8395 final int targetUserId;
8396 final int userHandle = readIntAttribute(in,
8397 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8398 if (userHandle != UserHandle.USER_NULL) {
8399 // For backwards compatibility.
8400 sourceUserId = userHandle;
8401 targetUserId = userHandle;
8403 sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8404 targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8406 final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8407 final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8408 final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8409 final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8410 final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8411 final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8413 // Sanity check that provider still belongs to source package
8414 final ProviderInfo pi = getProviderInfoLocked(
8415 uri.getAuthority(), sourceUserId);
8416 if (pi != null && sourcePkg.equals(pi.packageName)) {
8419 targetUid = AppGlobals.getPackageManager().getPackageUid(
8420 targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8421 } catch (RemoteException e) {
8423 if (targetUid != -1) {
8424 final UriPermission perm = findOrCreateUriPermissionLocked(
8425 sourcePkg, targetPkg, targetUid,
8426 new GrantUri(sourceUserId, uri, prefix));
8427 perm.initPersistedModes(modeFlags, createdTime);
8430 Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8431 + " but instead found " + pi);
8436 } catch (FileNotFoundException e) {
8437 // Missing grants is okay
8438 } catch (IOException e) {
8439 Slog.wtf(TAG, "Failed reading Uri grants", e);
8440 } catch (XmlPullParserException e) {
8441 Slog.wtf(TAG, "Failed reading Uri grants", e);
8443 IoUtils.closeQuietly(fis);
8448 * @param uri This uri must NOT contain an embedded userId.
8449 * @param userId The userId in which the uri is to be resolved.
8452 public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8453 enforceNotIsolatedCaller("takePersistableUriPermission");
8455 Preconditions.checkFlagsArgument(modeFlags,
8456 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8458 synchronized (this) {
8459 final int callingUid = Binder.getCallingUid();
8460 boolean persistChanged = false;
8461 GrantUri grantUri = new GrantUri(userId, uri, false);
8463 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8464 new GrantUri(userId, uri, false));
8465 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8466 new GrantUri(userId, uri, true));
8468 final boolean exactValid = (exactPerm != null)
8469 && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8470 final boolean prefixValid = (prefixPerm != null)
8471 && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8473 if (!(exactValid || prefixValid)) {
8474 throw new SecurityException("No persistable permission grants found for UID "
8475 + callingUid + " and Uri " + grantUri.toSafeString());
8479 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8482 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8485 persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8487 if (persistChanged) {
8488 schedulePersistUriGrants();
8494 * @param uri This uri must NOT contain an embedded userId.
8495 * @param userId The userId in which the uri is to be resolved.
8498 public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8499 enforceNotIsolatedCaller("releasePersistableUriPermission");
8501 Preconditions.checkFlagsArgument(modeFlags,
8502 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8504 synchronized (this) {
8505 final int callingUid = Binder.getCallingUid();
8506 boolean persistChanged = false;
8508 UriPermission exactPerm = findUriPermissionLocked(callingUid,
8509 new GrantUri(userId, uri, false));
8510 UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8511 new GrantUri(userId, uri, true));
8512 if (exactPerm == null && prefixPerm == null) {
8513 throw new SecurityException("No permission grants found for UID " + callingUid
8514 + " and Uri " + uri.toSafeString());
8517 if (exactPerm != null) {
8518 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8519 removeUriPermissionIfNeededLocked(exactPerm);
8521 if (prefixPerm != null) {
8522 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8523 removeUriPermissionIfNeededLocked(prefixPerm);
8526 if (persistChanged) {
8527 schedulePersistUriGrants();
8533 * Prune any older {@link UriPermission} for the given UID until outstanding
8534 * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8536 * @return if any mutations occured that require persisting.
8538 private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8539 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8540 if (perms == null) return false;
8541 if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8543 final ArrayList<UriPermission> persisted = Lists.newArrayList();
8544 for (UriPermission perm : perms.values()) {
8545 if (perm.persistedModeFlags != 0) {
8546 persisted.add(perm);
8550 final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8551 if (trimCount <= 0) return false;
8553 Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8554 for (int i = 0; i < trimCount; i++) {
8555 final UriPermission perm = persisted.get(i);
8557 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8558 "Trimming grant created at " + perm.persistedCreateTime);
8560 perm.releasePersistableModes(~0);
8561 removeUriPermissionIfNeededLocked(perm);
8568 public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8569 String packageName, boolean incoming) {
8570 enforceNotIsolatedCaller("getPersistedUriPermissions");
8571 Preconditions.checkNotNull(packageName, "packageName");
8573 final int callingUid = Binder.getCallingUid();
8574 final IPackageManager pm = AppGlobals.getPackageManager();
8576 final int packageUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
8577 UserHandle.getUserId(callingUid));
8578 if (packageUid != callingUid) {
8579 throw new SecurityException(
8580 "Package " + packageName + " does not belong to calling UID " + callingUid);
8582 } catch (RemoteException e) {
8583 throw new SecurityException("Failed to verify package name ownership");
8586 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8587 synchronized (this) {
8589 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8591 if (perms == null) {
8592 Slog.w(TAG, "No permission grants found for " + packageName);
8594 for (UriPermission perm : perms.values()) {
8595 if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8596 result.add(perm.buildPersistedPublicApiObject());
8601 final int size = mGrantedUriPermissions.size();
8602 for (int i = 0; i < size; i++) {
8603 final ArrayMap<GrantUri, UriPermission> perms =
8604 mGrantedUriPermissions.valueAt(i);
8605 for (UriPermission perm : perms.values()) {
8606 if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8607 result.add(perm.buildPersistedPublicApiObject());
8613 return new ParceledListSlice<android.content.UriPermission>(result);
8617 public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8618 String packageName, int userId) {
8619 enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8620 "getGrantedUriPermissions");
8622 final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8623 synchronized (this) {
8624 final int size = mGrantedUriPermissions.size();
8625 for (int i = 0; i < size; i++) {
8626 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8627 for (UriPermission perm : perms.values()) {
8628 if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8629 && perm.persistedModeFlags != 0) {
8630 result.add(perm.buildPersistedPublicApiObject());
8635 return new ParceledListSlice<android.content.UriPermission>(result);
8639 public void clearGrantedUriPermissions(String packageName, int userId) {
8640 enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8641 "clearGrantedUriPermissions");
8642 removeUriPermissionsForPackageLocked(packageName, userId, true);
8646 public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8647 synchronized (this) {
8649 who != null ? getRecordForAppLocked(who) : null;
8650 if (app == null) return;
8652 Message msg = Message.obtain();
8653 msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8655 msg.arg1 = waiting ? 1 : 0;
8656 mUiHandler.sendMessage(msg);
8661 public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8662 final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8663 final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8664 outInfo.availMem = Process.getFreeMemory();
8665 outInfo.totalMem = Process.getTotalMemory();
8666 outInfo.threshold = homeAppMem;
8667 outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8668 outInfo.hiddenAppThreshold = cachedAppMem;
8669 outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8670 ProcessList.SERVICE_ADJ);
8671 outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8672 ProcessList.VISIBLE_APP_ADJ);
8673 outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8674 ProcessList.FOREGROUND_APP_ADJ);
8677 // =========================================================
8679 // =========================================================
8682 public List<IAppTask> getAppTasks(String callingPackage) {
8683 int callingUid = Binder.getCallingUid();
8684 long ident = Binder.clearCallingIdentity();
8686 synchronized(this) {
8687 ArrayList<IAppTask> list = new ArrayList<IAppTask>();
8689 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
8691 final int N = mRecentTasks.size();
8692 for (int i = 0; i < N; i++) {
8693 TaskRecord tr = mRecentTasks.get(i);
8694 // Skip tasks that do not match the caller. We don't need to verify
8695 // callingPackage, because we are also limiting to callingUid and know
8696 // that will limit to the correct security sandbox.
8697 if (tr.effectiveUid != callingUid) {
8700 Intent intent = tr.getBaseIntent();
8701 if (intent == null ||
8702 !callingPackage.equals(intent.getComponent().getPackageName())) {
8705 ActivityManager.RecentTaskInfo taskInfo =
8706 createRecentTaskInfoFromTaskRecord(tr);
8707 AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
8711 Binder.restoreCallingIdentity(ident);
8718 public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
8719 final int callingUid = Binder.getCallingUid();
8720 ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
8722 synchronized(this) {
8723 if (DEBUG_ALL) Slog.v(
8724 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
8726 final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
8729 // TODO: Improve with MRU list from all ActivityStacks.
8730 mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
8737 * Creates a new RecentTaskInfo from a TaskRecord.
8739 private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
8740 // Update the task description to reflect any changes in the task stack
8741 tr.updateTaskDescription();
8743 // Compose the recent task info
8744 ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
8745 rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
8746 rti.persistentId = tr.taskId;
8747 rti.baseIntent = new Intent(tr.getBaseIntent());
8748 rti.origActivity = tr.origActivity;
8749 rti.realActivity = tr.realActivity;
8750 rti.description = tr.lastDescription;
8751 rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
8752 rti.userId = tr.userId;
8753 rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
8754 rti.firstActiveTime = tr.firstActiveTime;
8755 rti.lastActiveTime = tr.lastActiveTime;
8756 rti.affiliatedTaskId = tr.mAffiliatedTaskId;
8757 rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
8758 rti.numActivities = 0;
8759 if (tr.mBounds != null) {
8760 rti.bounds = new Rect(tr.mBounds);
8762 rti.isDockable = tr.canGoInDockedStack();
8764 ActivityRecord base = null;
8765 ActivityRecord top = null;
8768 for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
8769 tmp = tr.mActivities.get(i);
8770 if (tmp.finishing) {
8774 if (top == null || (top.state == ActivityState.INITIALIZING)) {
8777 rti.numActivities++;
8780 rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
8781 rti.topActivity = (top != null) ? top.intent.getComponent() : null;
8786 private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
8787 boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
8788 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
8790 if (checkPermission(android.Manifest.permission.GET_TASKS,
8791 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
8792 // Temporary compatibility: some existing apps on the system image may
8793 // still be requesting the old permission and not switched to the new
8794 // one; if so, we'll still allow them full access. This means we need
8795 // to see if they are holding the old permission and are a system app.
8797 if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
8799 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8800 + " is using old GET_TASKS but privileged; allowing");
8802 } catch (RemoteException e) {
8807 if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
8808 + " does not hold REAL_GET_TASKS; limiting output");
8814 public List<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags, int userId) {
8815 final int callingUid = Binder.getCallingUid();
8816 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
8817 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
8819 final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
8820 final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
8821 synchronized (this) {
8822 final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
8824 final boolean detailed = checkCallingPermission(
8825 android.Manifest.permission.GET_DETAILED_TASKS)
8826 == PackageManager.PERMISSION_GRANTED;
8828 if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
8829 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
8830 return Collections.emptyList();
8832 mRecentTasks.loadUserRecentsLocked(userId);
8834 final int recentsCount = mRecentTasks.size();
8835 ArrayList<ActivityManager.RecentTaskInfo> res =
8836 new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
8838 final Set<Integer> includedUsers;
8839 if (includeProfiles) {
8840 includedUsers = mUserController.getProfileIds(userId);
8842 includedUsers = new HashSet<>();
8844 includedUsers.add(Integer.valueOf(userId));
8846 for (int i = 0; i < recentsCount && maxNum > 0; i++) {
8847 TaskRecord tr = mRecentTasks.get(i);
8848 // Only add calling user or related users recent tasks
8849 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
8850 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
8854 if (tr.realActivitySuspended) {
8855 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
8859 // Return the entry if desired by the caller. We always return
8860 // the first entry, because callers always expect this to be the
8861 // foreground app. We may filter others if the caller has
8862 // not supplied RECENT_WITH_EXCLUDED and there is some reason
8863 // we should exclude the entry.
8867 || (tr.intent == null)
8868 || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
8871 // If the caller doesn't have the GET_TASKS permission, then only
8872 // allow them to see a small subset of tasks -- their own and home.
8873 if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
8874 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
8878 if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
8879 if (tr.stack != null && tr.stack.isHomeStack()) {
8880 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8881 "Skipping, home stack task: " + tr);
8885 if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TASKS) != 0) {
8886 if (tr.stack != null && tr.stack.isDockedStack()) {
8887 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8888 "Skipping, docked stack task: " + tr);
8892 if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
8893 if (tr.stack != null && tr.stack.isPinnedStack()) {
8894 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8895 "Skipping, pinned stack task: " + tr);
8899 if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
8900 // Don't include auto remove tasks that are finished or finishing.
8901 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8902 "Skipping, auto-remove without activity: " + tr);
8905 if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
8906 && !tr.isAvailable) {
8907 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8908 "Skipping, unavail real act: " + tr);
8912 if (!tr.mUserSetupComplete) {
8913 // Don't include task launched while user is not done setting-up.
8914 if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
8915 "Skipping, user setup not complete: " + tr);
8919 ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
8921 rti.baseIntent.replaceExtras((Bundle)null);
8933 public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
8934 synchronized (this) {
8935 enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
8936 "getTaskThumbnail()");
8937 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
8938 id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
8940 return tr.getTaskThumbnailLocked();
8947 public int addAppTask(IBinder activityToken, Intent intent,
8948 ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
8949 final int callingUid = Binder.getCallingUid();
8950 final long callingIdent = Binder.clearCallingIdentity();
8953 synchronized (this) {
8954 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8956 throw new IllegalArgumentException("Activity does not exist; token="
8959 ComponentName comp = intent.getComponent();
8961 throw new IllegalArgumentException("Intent " + intent
8962 + " must specify explicit component");
8964 if (thumbnail.getWidth() != mThumbnailWidth
8965 || thumbnail.getHeight() != mThumbnailHeight) {
8966 throw new IllegalArgumentException("Bad thumbnail size: got "
8967 + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
8968 + mThumbnailWidth + "x" + mThumbnailHeight);
8970 if (intent.getSelector() != null) {
8971 intent.setSelector(null);
8973 if (intent.getSourceBounds() != null) {
8974 intent.setSourceBounds(null);
8976 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
8977 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
8978 // The caller has added this as an auto-remove task... that makes no
8979 // sense, so turn off auto-remove.
8980 intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
8982 } else if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_TASK) != 0) {
8983 // Must be a new task.
8984 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
8986 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
8987 mLastAddedTaskActivity = null;
8989 ActivityInfo ainfo = mLastAddedTaskActivity;
8990 if (ainfo == null) {
8991 ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
8992 comp, 0, UserHandle.getUserId(callingUid));
8993 if (ainfo.applicationInfo.uid != callingUid) {
8994 throw new SecurityException(
8995 "Can't add task for another application: target uid="
8996 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9000 // Use the full screen as the context for the task thumbnail
9001 final Point displaySize = new Point();
9002 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9003 r.task.stack.getDisplaySize(displaySize);
9004 thumbnailInfo.taskWidth = displaySize.x;
9005 thumbnailInfo.taskHeight = displaySize.y;
9006 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9008 TaskRecord task = new TaskRecord(this,
9009 mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9010 ainfo, intent, description, thumbnailInfo);
9012 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9014 // If this would have caused a trim, then we'll abort because that
9015 // means it would be added at the end of the list but then just removed.
9016 return INVALID_TASK_ID;
9019 final int N = mRecentTasks.size();
9020 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9021 final TaskRecord tr = mRecentTasks.remove(N - 1);
9022 tr.removedFromRecents();
9025 task.inRecents = true;
9026 mRecentTasks.add(task);
9027 r.task.stack.addTask(task, false, "addAppTask");
9029 task.setLastThumbnailLocked(thumbnail);
9030 task.freeLastThumbnail();
9035 Binder.restoreCallingIdentity(callingIdent);
9040 public Point getAppTaskThumbnailSize() {
9041 synchronized (this) {
9042 return new Point(mThumbnailWidth, mThumbnailHeight);
9047 public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9048 synchronized (this) {
9049 ActivityRecord r = ActivityRecord.isInStackLocked(token);
9051 r.setTaskDescription(td);
9052 r.task.updateTaskDescription();
9058 public void setTaskResizeable(int taskId, int resizeableMode) {
9059 synchronized (this) {
9060 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9061 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9063 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9066 if (task.mResizeMode != resizeableMode) {
9067 task.mResizeMode = resizeableMode;
9068 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9069 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9070 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9076 public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9077 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9078 long ident = Binder.clearCallingIdentity();
9080 synchronized (this) {
9081 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9083 Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9086 int stackId = task.stack.mStackId;
9087 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9088 // in crop windows resize mode or if the task size is affected by the docked stack
9089 // changing size. No need to update configuration.
9090 if (bounds != null && task.inCropWindowsResizeMode()
9091 && mStackSupervisor.isStackDockedInEffect(stackId)) {
9092 mWindowManager.scrollTask(task.taskId, bounds);
9096 // Place the task in the right stack if it isn't there already based on
9097 // the requested bounds.
9098 // The stack transition logic is:
9099 // - a null bounds on a freeform task moves that task to fullscreen
9100 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9101 // that task to freeform
9102 // - otherwise the task is not moved
9103 if (!StackId.isTaskResizeAllowed(stackId)) {
9104 throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9106 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9107 stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9108 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9109 stackId = FREEFORM_WORKSPACE_STACK_ID;
9111 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9112 if (stackId != task.stack.mStackId) {
9113 mStackSupervisor.moveTaskToStackUncheckedLocked(
9114 task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9115 preserveWindow = false;
9118 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9119 false /* deferResume */);
9122 Binder.restoreCallingIdentity(ident);
9127 public Rect getTaskBounds(int taskId) {
9128 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9129 long ident = Binder.clearCallingIdentity();
9130 Rect rect = new Rect();
9132 synchronized (this) {
9133 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9134 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9136 Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9139 if (task.stack != null) {
9140 // Return the bounds from window manager since it will be adjusted for various
9141 // things like the presense of a docked stack for tasks that aren't resizeable.
9142 mWindowManager.getTaskBounds(task.taskId, rect);
9144 // Task isn't in window manager yet since it isn't associated with a stack.
9145 // Return the persist value from activity manager
9146 if (task.mBounds != null) {
9147 rect.set(task.mBounds);
9148 } else if (task.mLastNonFullscreenBounds != null) {
9149 rect.set(task.mLastNonFullscreenBounds);
9154 Binder.restoreCallingIdentity(ident);
9160 public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9161 if (userId != UserHandle.getCallingUserId()) {
9162 enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9163 "getTaskDescriptionIcon");
9165 final File passedIconFile = new File(filePath);
9166 final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9167 passedIconFile.getName());
9168 if (!legitIconFile.getPath().equals(filePath)
9169 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9170 throw new IllegalArgumentException("Bad file path: " + filePath
9171 + " passed for userId " + userId);
9173 return mRecentTasks.getTaskDescriptionIcon(filePath);
9177 public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9178 throws RemoteException {
9179 if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9180 opts.getCustomInPlaceResId() == 0) {
9181 throw new IllegalArgumentException("Expected in-place ActivityOption " +
9182 "with valid animation");
9184 mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9185 mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9186 opts.getCustomInPlaceResId());
9187 mWindowManager.executeAppTransition();
9190 private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9191 boolean removeFromRecents) {
9192 if (removeFromRecents) {
9193 mRecentTasks.remove(tr);
9194 tr.removedFromRecents();
9196 ComponentName component = tr.getBaseIntent().getComponent();
9197 if (component == null) {
9198 Slog.w(TAG, "No component for base intent of task: " + tr);
9202 // Find any running services associated with this app and stop if needed.
9203 mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9209 // Determine if the process(es) for this task should be killed.
9210 final String pkg = component.getPackageName();
9211 ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9212 ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9213 for (int i = 0; i < pmap.size(); i++) {
9215 SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9216 for (int j = 0; j < uids.size(); j++) {
9217 ProcessRecord proc = uids.valueAt(j);
9218 if (proc.userId != tr.userId) {
9219 // Don't kill process for a different user.
9222 if (proc == mHomeProcess) {
9223 // Don't kill the home process along with tasks from the same package.
9226 if (!proc.pkgList.containsKey(pkg)) {
9227 // Don't kill process that is not associated with this task.
9231 for (int k = 0; k < proc.activities.size(); k++) {
9232 TaskRecord otherTask = proc.activities.get(k).task;
9233 if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9234 // Don't kill process(es) that has an activity in a different task that is
9240 if (proc.foregroundServices) {
9241 // Don't kill process(es) with foreground service.
9245 // Add process to kill list.
9246 procsToKill.add(proc);
9250 // Kill the running processes.
9251 for (int i = 0; i < procsToKill.size(); i++) {
9252 ProcessRecord pr = procsToKill.get(i);
9253 if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9254 && pr.curReceiver == null) {
9255 pr.kill("remove task", true);
9257 // We delay killing processes that are not in the background or running a receiver.
9258 pr.waitingToKill = "remove task";
9263 private void removeTasksByPackageNameLocked(String packageName, int userId) {
9264 // Remove all tasks with activities in the specified package from the list of recent tasks
9265 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9266 TaskRecord tr = mRecentTasks.get(i);
9267 if (tr.userId != userId) continue;
9269 ComponentName cn = tr.intent.getComponent();
9270 if (cn != null && cn.getPackageName().equals(packageName)) {
9271 // If the package name matches, remove the task.
9272 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9277 private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9280 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9281 TaskRecord tr = mRecentTasks.get(i);
9282 if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9286 ComponentName cn = tr.intent.getComponent();
9287 final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9288 && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9289 if (sameComponent) {
9290 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9296 * Removes the task with the specified task id.
9298 * @param taskId Identifier of the task to be removed.
9299 * @param killProcess Kill any process associated with the task if possible.
9300 * @param removeFromRecents Whether to also remove the task from recents.
9301 * @return Returns true if the given task was found and removed.
9303 private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9304 boolean removeFromRecents) {
9305 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9306 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9308 tr.removeTaskActivitiesLocked();
9309 cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9310 if (tr.isPersistable) {
9311 notifyTaskPersisterLocked(null, true);
9315 Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9320 public void removeStack(int stackId) {
9321 enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9322 if (stackId == HOME_STACK_ID) {
9323 throw new IllegalArgumentException("Removing home stack is not allowed.");
9326 synchronized (this) {
9327 final long ident = Binder.clearCallingIdentity();
9329 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9330 if (stack == null) {
9333 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9334 for (int i = tasks.size() - 1; i >= 0; i--) {
9335 removeTaskByIdLocked(
9336 tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9339 Binder.restoreCallingIdentity(ident);
9345 public boolean removeTask(int taskId) {
9346 enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9347 synchronized (this) {
9348 final long ident = Binder.clearCallingIdentity();
9350 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9352 Binder.restoreCallingIdentity(ident);
9358 * TODO: Add mController hook
9361 public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9362 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9364 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9365 synchronized(this) {
9366 moveTaskToFrontLocked(taskId, flags, bOptions);
9370 void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9371 ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9373 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9374 Binder.getCallingUid(), -1, -1, "Task to front")) {
9375 ActivityOptions.abort(options);
9378 final long origId = Binder.clearCallingIdentity();
9380 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9382 Slog.d(TAG, "Could not find task for id: "+ taskId);
9385 if (mStackSupervisor.isLockTaskModeViolation(task)) {
9386 mStackSupervisor.showLockTaskToast();
9387 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9390 final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9391 if (prev != null && prev.isRecentsActivity()) {
9392 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9394 mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront");
9396 Binder.restoreCallingIdentity(origId);
9398 ActivityOptions.abort(options);
9402 * Moves an activity, and all of the other activities within the same task, to the bottom
9403 * of the history stack. The activity's order within the task is unchanged.
9405 * @param token A reference to the activity we wish to move
9406 * @param nonRoot If false then this only works if the activity is the root
9407 * of a task; if true it will work for any activity in a task.
9408 * @return Returns true if the move completed, false if not.
9411 public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9412 enforceNotIsolatedCaller("moveActivityTaskToBack");
9413 synchronized(this) {
9414 final long origId = Binder.clearCallingIdentity();
9416 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9417 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9419 if (mStackSupervisor.isLockedTask(task)) {
9420 mStackSupervisor.showLockTaskToast();
9423 return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9426 Binder.restoreCallingIdentity(origId);
9433 public void moveTaskBackwards(int task) {
9434 enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9435 "moveTaskBackwards()");
9437 synchronized(this) {
9438 if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9439 Binder.getCallingUid(), -1, -1, "Task backwards")) {
9442 final long origId = Binder.clearCallingIdentity();
9443 moveTaskBackwardsLocked(task);
9444 Binder.restoreCallingIdentity(origId);
9448 private final void moveTaskBackwardsLocked(int task) {
9449 Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9453 public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9454 IActivityContainerCallback callback) throws RemoteException {
9455 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9456 synchronized (this) {
9457 if (parentActivityToken == null) {
9458 throw new IllegalArgumentException("parent token must not be null");
9460 ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9464 if (callback == null) {
9465 throw new IllegalArgumentException("callback must not be null");
9467 return mStackSupervisor.createVirtualActivityContainer(r, callback);
9472 public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9473 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9474 synchronized (this) {
9475 mStackSupervisor.deleteActivityContainer(container);
9480 public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9481 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9482 synchronized (this) {
9483 final int stackId = mStackSupervisor.getNextStackId();
9484 final ActivityStack stack =
9485 mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9486 if (stack == null) {
9489 return stack.mActivityContainer;
9494 public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9495 synchronized (this) {
9496 ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9497 if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9498 return stack.mActivityContainer.getDisplayId();
9500 return Display.DEFAULT_DISPLAY;
9505 public int getActivityStackId(IBinder token) throws RemoteException {
9506 synchronized (this) {
9507 ActivityStack stack = ActivityRecord.getStackLocked(token);
9508 if (stack == null) {
9509 return INVALID_STACK_ID;
9511 return stack.mStackId;
9516 public void exitFreeformMode(IBinder token) throws RemoteException {
9517 synchronized (this) {
9518 long ident = Binder.clearCallingIdentity();
9520 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9522 throw new IllegalArgumentException(
9523 "exitFreeformMode: No activity record matching token=" + token);
9525 final ActivityStack stack = r.getStackLocked(token);
9526 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9527 throw new IllegalStateException(
9528 "exitFreeformMode: You can only go fullscreen from freeform.");
9530 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9531 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9532 ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9534 Binder.restoreCallingIdentity(ident);
9540 public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9541 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9542 if (stackId == HOME_STACK_ID) {
9543 throw new IllegalArgumentException(
9544 "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9546 synchronized (this) {
9547 long ident = Binder.clearCallingIdentity();
9549 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9550 + " to stackId=" + stackId + " toTop=" + toTop);
9551 if (stackId == DOCKED_STACK_ID) {
9552 mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9553 null /* initialBounds */);
9555 mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop, !FORCE_FOCUS,
9556 "moveTaskToStack", ANIMATE);
9558 Binder.restoreCallingIdentity(ident);
9564 public void swapDockedAndFullscreenStack() throws RemoteException {
9565 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9566 synchronized (this) {
9567 long ident = Binder.clearCallingIdentity();
9569 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9570 FULLSCREEN_WORKSPACE_STACK_ID);
9571 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9573 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9574 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9576 if (topTask == null || tasks == null || tasks.size() == 0) {
9578 "Unable to swap tasks, either docked or fullscreen stack is empty.");
9582 // TODO: App transition
9583 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9585 // Defer the resume so resume/pausing while moving stacks is dangerous.
9586 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9587 false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9588 ANIMATE, true /* deferResume */);
9589 final int size = tasks.size();
9590 for (int i = 0; i < size; i++) {
9591 final int id = tasks.get(i).taskId;
9592 if (id == topTask.taskId) {
9595 mStackSupervisor.moveTaskToStackLocked(id,
9596 FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9597 "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9600 // Because we deferred the resume, to avoid conflicts with stack switches while
9601 // resuming, we need to do it after all the tasks are moved.
9602 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9603 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9605 mWindowManager.executeAppTransition();
9607 Binder.restoreCallingIdentity(ident);
9613 * Moves the input task to the docked stack.
9615 * @param taskId Id of task to move.
9616 * @param createMode The mode the docked stack should be created in if it doesn't exist
9618 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9620 * {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9621 * @param toTop If the task and stack should be moved to the top.
9622 * @param animate Whether we should play an animation for the moving the task
9623 * @param initialBounds If the docked stack gets created, it will use these bounds for the
9624 * docked stack. Pass {@code null} to use default bounds.
9627 public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9628 Rect initialBounds) {
9629 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9630 synchronized (this) {
9631 long ident = Binder.clearCallingIdentity();
9633 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9634 + " to createMode=" + createMode + " toTop=" + toTop);
9635 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9636 return mStackSupervisor.moveTaskToStackLocked(
9637 taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS,
9638 "moveTaskToDockedStack", animate);
9640 Binder.restoreCallingIdentity(ident);
9646 * Moves the top activity in the input stackId to the pinned stack.
9648 * @param stackId Id of stack to move the top activity to pinned stack.
9649 * @param bounds Bounds to use for pinned stack.
9651 * @return True if the top activity of the input stack was successfully moved to the pinned
9655 public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9656 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9657 synchronized (this) {
9658 if (!mSupportsPictureInPicture) {
9659 throw new IllegalStateException("moveTopActivityToPinnedStack:"
9660 + "Device doesn't support picture-in-pciture mode");
9663 long ident = Binder.clearCallingIdentity();
9665 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
9667 Binder.restoreCallingIdentity(ident);
9673 public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
9674 boolean preserveWindows, boolean animate) {
9675 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
9676 long ident = Binder.clearCallingIdentity();
9678 synchronized (this) {
9680 if (stackId == PINNED_STACK_ID) {
9681 mWindowManager.animateResizePinnedStack(bounds);
9683 throw new IllegalArgumentException("Stack: " + stackId
9684 + " doesn't support animated resize.");
9687 mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
9688 null /* tempTaskInsetBounds */, preserveWindows,
9689 allowResizeInDockedMode);
9693 Binder.restoreCallingIdentity(ident);
9698 public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
9699 Rect tempDockedTaskInsetBounds,
9700 Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
9701 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9702 "resizeDockedStack()");
9703 long ident = Binder.clearCallingIdentity();
9705 synchronized (this) {
9706 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
9707 tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
9711 Binder.restoreCallingIdentity(ident);
9716 public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
9717 enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
9718 "resizePinnedStack()");
9719 final long ident = Binder.clearCallingIdentity();
9721 synchronized (this) {
9722 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
9725 Binder.restoreCallingIdentity(ident);
9730 public void positionTaskInStack(int taskId, int stackId, int position) {
9731 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
9732 if (stackId == HOME_STACK_ID) {
9733 throw new IllegalArgumentException(
9734 "positionTaskInStack: Attempt to change the position of task "
9735 + taskId + " in/to home stack");
9737 synchronized (this) {
9738 long ident = Binder.clearCallingIdentity();
9740 if (DEBUG_STACK) Slog.d(TAG_STACK,
9741 "positionTaskInStack: positioning task=" + taskId
9742 + " in stackId=" + stackId + " at position=" + position);
9743 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
9745 Binder.restoreCallingIdentity(ident);
9751 public List<StackInfo> getAllStackInfos() {
9752 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
9753 long ident = Binder.clearCallingIdentity();
9755 synchronized (this) {
9756 return mStackSupervisor.getAllStackInfosLocked();
9759 Binder.restoreCallingIdentity(ident);
9764 public StackInfo getStackInfo(int stackId) {
9765 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9766 long ident = Binder.clearCallingIdentity();
9768 synchronized (this) {
9769 return mStackSupervisor.getStackInfoLocked(stackId);
9772 Binder.restoreCallingIdentity(ident);
9777 public boolean isInHomeStack(int taskId) {
9778 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
9779 long ident = Binder.clearCallingIdentity();
9781 synchronized (this) {
9782 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9783 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9784 return tr != null && tr.stack != null && tr.stack.isHomeStack();
9787 Binder.restoreCallingIdentity(ident);
9792 public int getTaskForActivity(IBinder token, boolean onlyRoot) {
9793 synchronized(this) {
9794 return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
9799 public void updateDeviceOwner(String packageName) {
9800 final int callingUid = Binder.getCallingUid();
9801 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9802 throw new SecurityException("updateDeviceOwner called from non-system process");
9804 synchronized (this) {
9805 mDeviceOwnerName = packageName;
9810 public void updateLockTaskPackages(int userId, String[] packages) {
9811 final int callingUid = Binder.getCallingUid();
9812 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
9813 throw new SecurityException("updateLockTaskPackage called from non-system process");
9815 synchronized (this) {
9816 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
9817 Arrays.toString(packages));
9818 mLockTaskPackages.put(userId, packages);
9819 mStackSupervisor.onLockTaskPackagesUpdatedLocked();
9824 void startLockTaskModeLocked(TaskRecord task) {
9825 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
9826 if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
9830 // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
9831 // is initiated by system after the pinning request was shown and locked mode is initiated
9832 // by an authorized app directly
9833 final int callingUid = Binder.getCallingUid();
9834 boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
9835 long ident = Binder.clearCallingIdentity();
9837 final ActivityStack stack = mStackSupervisor.getFocusedStack();
9838 if (!isSystemInitiated) {
9839 task.mLockTaskUid = callingUid;
9840 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
9841 // startLockTask() called by app and task mode is lockTaskModeDefault.
9842 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
9843 StatusBarManagerInternal statusBarManager =
9844 LocalServices.getService(StatusBarManagerInternal.class);
9845 if (statusBarManager != null) {
9846 statusBarManager.showScreenPinningRequest();
9851 if (stack == null || task != stack.topTask()) {
9852 throw new IllegalArgumentException("Invalid task, not in foreground");
9855 if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
9857 mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
9858 ActivityManager.LOCK_TASK_MODE_PINNED :
9859 ActivityManager.LOCK_TASK_MODE_LOCKED,
9860 "startLockTask", true);
9862 Binder.restoreCallingIdentity(ident);
9867 public void startLockTaskMode(int taskId) {
9868 synchronized (this) {
9869 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9871 startLockTaskModeLocked(task);
9877 public void startLockTaskMode(IBinder token) {
9878 synchronized (this) {
9879 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9883 final TaskRecord task = r.task;
9885 startLockTaskModeLocked(task);
9891 public void startLockTaskModeOnCurrent() throws RemoteException {
9892 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startLockTaskModeOnCurrent");
9893 long ident = Binder.clearCallingIdentity();
9895 synchronized (this) {
9896 ActivityRecord r = mStackSupervisor.topRunningActivityLocked();
9898 startLockTaskModeLocked(r.task);
9902 Binder.restoreCallingIdentity(ident);
9907 public void stopLockTaskMode() {
9908 final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
9909 if (lockTask == null) {
9910 // Our work here is done.
9914 final int callingUid = Binder.getCallingUid();
9915 final int lockTaskUid = lockTask.mLockTaskUid;
9916 // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
9917 // It is possible lockTaskMode was started by the system process because
9918 // android:lockTaskMode is set to a locking value in the application manifest instead of
9919 // the app calling startLockTaskMode. In this case {@link TaskRecord.mLockTaskUid} will
9920 // be 0, so we compare the callingUid to the {@link TaskRecord.effectiveUid} instead.
9921 if (getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_LOCKED &&
9922 callingUid != lockTaskUid
9923 && (lockTaskUid != 0
9924 || (lockTaskUid == 0 && callingUid != lockTask.effectiveUid))) {
9925 throw new SecurityException("Invalid uid, expected " + lockTaskUid
9926 + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
9929 long ident = Binder.clearCallingIdentity();
9931 Log.d(TAG, "stopLockTaskMode");
9933 synchronized (this) {
9934 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
9935 "stopLockTask", true);
9938 Binder.restoreCallingIdentity(ident);
9943 public void stopLockTaskModeOnCurrent() throws RemoteException {
9944 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "stopLockTaskModeOnCurrent");
9945 long ident = Binder.clearCallingIdentity();
9949 Binder.restoreCallingIdentity(ident);
9954 public boolean isInLockTaskMode() {
9955 return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
9959 public int getLockTaskModeState() {
9960 synchronized (this) {
9961 return mStackSupervisor.getLockTaskModeState();
9966 public void showLockTaskEscapeMessage(IBinder token) {
9967 synchronized (this) {
9968 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9972 mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
9976 // =========================================================
9977 // CONTENT PROVIDERS
9978 // =========================================================
9980 private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
9981 List<ProviderInfo> providers = null;
9983 providers = AppGlobals.getPackageManager()
9984 .queryContentProviders(app.processName, app.uid,
9985 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
9986 | MATCH_DEBUG_TRIAGED_MISSING)
9988 } catch (RemoteException ex) {
9990 if (DEBUG_MU) Slog.v(TAG_MU,
9991 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
9992 int userId = app.userId;
9993 if (providers != null) {
9994 int N = providers.size();
9995 app.pubProviders.ensureCapacity(N + app.pubProviders.size());
9996 for (int i=0; i<N; i++) {
9998 (ProviderInfo)providers.get(i);
9999 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10000 cpi.name, cpi.flags);
10001 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10002 // This is a singleton provider, but a user besides the
10003 // default user is asking to initialize a process it runs
10004 // in... well, no, it doesn't actually run in this process,
10005 // it runs in the process of the default user. Get rid of it.
10006 providers.remove(i);
10012 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10013 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10015 cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10016 mProviderMap.putProviderByClass(comp, cpr);
10018 if (DEBUG_MU) Slog.v(TAG_MU,
10019 "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10020 app.pubProviders.put(cpi.name, cpr);
10021 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10022 // Don't add this if it is a platform component that is marked
10023 // to run in multiple processes, because this is actually
10024 // part of the framework so doesn't make sense to track as a
10025 // separate apk in the process.
10026 app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10029 notifyPackageUse(cpi.applicationInfo.packageName);
10036 * Check if {@link ProcessRecord} has a possible chance at accessing the
10037 * given {@link ProviderInfo}. Final permission checking is always done
10038 * in {@link ContentProvider}.
10040 private final String checkContentProviderPermissionLocked(
10041 ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10042 final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10043 final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10044 boolean checkedGrants = false;
10046 // Looking for cross-user grants before enforcing the typical cross-users permissions
10047 int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10048 if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10049 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10052 checkedGrants = true;
10054 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10055 ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10056 if (userId != tmpTargetUserId) {
10057 // When we actually went to determine the final targer user ID, this ended
10058 // up different than our initial check for the authority. This is because
10059 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10060 // SELF. So we need to re-check the grants again.
10061 checkedGrants = false;
10064 if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10065 cpi.applicationInfo.uid, cpi.exported)
10066 == PackageManager.PERMISSION_GRANTED) {
10069 if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10070 cpi.applicationInfo.uid, cpi.exported)
10071 == PackageManager.PERMISSION_GRANTED) {
10075 PathPermission[] pps = cpi.pathPermissions;
10077 int i = pps.length;
10080 PathPermission pp = pps[i];
10081 String pprperm = pp.getReadPermission();
10082 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10083 cpi.applicationInfo.uid, cpi.exported)
10084 == PackageManager.PERMISSION_GRANTED) {
10087 String ppwperm = pp.getWritePermission();
10088 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10089 cpi.applicationInfo.uid, cpi.exported)
10090 == PackageManager.PERMISSION_GRANTED) {
10095 if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10100 if (!cpi.exported) {
10101 msg = "Permission Denial: opening provider " + cpi.name
10102 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10103 + ", uid=" + callingUid + ") that is not exported from uid "
10104 + cpi.applicationInfo.uid;
10106 msg = "Permission Denial: opening provider " + cpi.name
10107 + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10108 + ", uid=" + callingUid + ") requires "
10109 + cpi.readPermission + " or " + cpi.writePermission;
10116 * Returns if the ContentProvider has granted a uri to callingUid
10118 boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10119 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10120 if (perms != null) {
10121 for (int i=perms.size()-1; i>=0; i--) {
10122 GrantUri grantUri = perms.keyAt(i);
10123 if (grantUri.sourceUserId == userId || !checkUser) {
10124 if (matchesProvider(grantUri.uri, cpi)) {
10134 * Returns true if the uri authority is one of the authorities specified in the provider.
10136 boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10137 String uriAuth = uri.getAuthority();
10138 String cpiAuth = cpi.authority;
10139 if (cpiAuth.indexOf(';') == -1) {
10140 return cpiAuth.equals(uriAuth);
10142 String[] cpiAuths = cpiAuth.split(";");
10143 int length = cpiAuths.length;
10144 for (int i = 0; i < length; i++) {
10145 if (cpiAuths[i].equals(uriAuth)) return true;
10150 ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10151 final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10153 for (int i=0; i<r.conProviders.size(); i++) {
10154 ContentProviderConnection conn = r.conProviders.get(i);
10155 if (conn.provider == cpr) {
10156 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10157 "Adding provider requested by "
10158 + r.processName + " from process "
10159 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10160 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10162 conn.stableCount++;
10163 conn.numStableIncs++;
10165 conn.unstableCount++;
10166 conn.numUnstableIncs++;
10171 ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10173 conn.stableCount = 1;
10174 conn.numStableIncs = 1;
10176 conn.unstableCount = 1;
10177 conn.numUnstableIncs = 1;
10179 cpr.connections.add(conn);
10180 r.conProviders.add(conn);
10181 startAssociationLocked(r.uid, r.processName, cpr.uid, cpr.name, cpr.info.processName);
10184 cpr.addExternalProcessHandleLocked(externalProcessToken);
10188 boolean decProviderCountLocked(ContentProviderConnection conn,
10189 ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10190 if (conn != null) {
10191 cpr = conn.provider;
10192 if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10193 "Removing provider requested by "
10194 + conn.client.processName + " from process "
10195 + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10196 + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10198 conn.stableCount--;
10200 conn.unstableCount--;
10202 if (conn.stableCount == 0 && conn.unstableCount == 0) {
10203 cpr.connections.remove(conn);
10204 conn.client.conProviders.remove(conn);
10205 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10206 // The client is more important than last activity -- note the time this
10207 // is happening, so we keep the old provider process around a bit as last
10208 // activity to avoid thrashing it.
10209 if (cpr.proc != null) {
10210 cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10213 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10218 cpr.removeExternalProcessHandleLocked(externalProcessToken);
10222 private void checkTime(long startTime, String where) {
10223 long now = SystemClock.elapsedRealtime();
10224 if ((now-startTime) > 1000) {
10225 // If we are taking more than a second, log about it.
10226 Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10230 private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10231 String name, IBinder token, boolean stable, int userId) {
10232 ContentProviderRecord cpr;
10233 ContentProviderConnection conn = null;
10234 ProviderInfo cpi = null;
10236 synchronized(this) {
10237 long startTime = SystemClock.elapsedRealtime();
10239 ProcessRecord r = null;
10240 if (caller != null) {
10241 r = getRecordForAppLocked(caller);
10243 throw new SecurityException(
10244 "Unable to find app for caller " + caller
10245 + " (pid=" + Binder.getCallingPid()
10246 + ") when getting content provider " + name);
10250 boolean checkCrossUser = true;
10252 checkTime(startTime, "getContentProviderImpl: getProviderByName");
10254 // First check if this content provider has been published...
10255 cpr = mProviderMap.getProviderByName(name, userId);
10256 // If that didn't work, check if it exists for user 0 and then
10257 // verify that it's a singleton provider before using it.
10258 if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10259 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10262 if (isSingleton(cpi.processName, cpi.applicationInfo,
10263 cpi.name, cpi.flags)
10264 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10265 userId = UserHandle.USER_SYSTEM;
10266 checkCrossUser = false;
10274 boolean providerRunning = cpr != null;
10275 if (providerRunning) {
10278 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10279 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10281 throw new SecurityException(msg);
10283 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10285 if (r != null && cpr.canRunHere(r)) {
10286 // This provider has been published or is in the process
10287 // of being published... but it is also allowed to run
10288 // in the caller's process, so don't make a connection
10289 // and just let the caller instantiate its own instance.
10290 ContentProviderHolder holder = cpr.newHolder(null);
10291 // don't give caller the provider object, it needs
10292 // to make its own.
10293 holder.provider = null;
10297 final long origId = Binder.clearCallingIdentity();
10299 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10301 // In this case the provider instance already exists, so we can
10302 // return it right away.
10303 conn = incProviderCountLocked(r, cpr, token, stable);
10304 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10305 if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10306 // If this is a perceptible app accessing the provider,
10307 // make sure to count it as being accessed and thus
10308 // back up on the LRU list. This is good because
10309 // content providers are often expensive to start.
10310 checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10311 updateLruProcessLocked(cpr.proc, false, null);
10312 checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10316 if (cpr.proc != null) {
10317 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10318 boolean success = updateOomAdjLocked(cpr.proc);
10319 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10320 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10321 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10322 // NOTE: there is still a race here where a signal could be
10323 // pending on the process even though we managed to update its
10324 // adj level. Not sure what to do about this, but at least
10325 // the race is now smaller.
10327 // Uh oh... it looks like the provider's process
10328 // has been killed on us. We need to wait for a new
10329 // process to be started, and make sure its death
10330 // doesn't kill our process.
10331 Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10332 + " is crashing; detaching " + r);
10333 boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10334 checkTime(startTime, "getContentProviderImpl: before appDied");
10335 appDiedLocked(cpr.proc);
10336 checkTime(startTime, "getContentProviderImpl: after appDied");
10338 // This wasn't the last ref our process had on
10339 // the provider... we have now been killed, bail.
10342 providerRunning = false;
10347 Binder.restoreCallingIdentity(origId);
10350 if (!providerRunning) {
10352 checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10353 cpi = AppGlobals.getPackageManager().
10354 resolveContentProvider(name,
10355 STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10356 checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10357 } catch (RemoteException ex) {
10362 // If the provider is a singleton AND
10363 // (it's a call within the same user || the provider is a
10365 // Then allow connecting to the singleton provider
10366 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10367 cpi.name, cpi.flags)
10368 && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10370 userId = UserHandle.USER_SYSTEM;
10372 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10373 checkTime(startTime, "getContentProviderImpl: got app info for user");
10376 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10377 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10379 throw new SecurityException(msg);
10381 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10383 if (!mProcessesReady && !mDidUpdate && !mWaitingUpdate
10384 && !cpi.processName.equals("system")) {
10385 // If this content provider does not run in the system
10386 // process, and the system is not yet ready to run other
10387 // processes, then fail fast instead of hanging.
10388 throw new IllegalArgumentException(
10389 "Attempt to launch content provider before system ready");
10392 // Make sure that the user who owns this provider is running. If not,
10393 // we don't want to allow it to run.
10394 if (!mUserController.isUserRunningLocked(userId, 0)) {
10395 Slog.w(TAG, "Unable to launch app "
10396 + cpi.applicationInfo.packageName + "/"
10397 + cpi.applicationInfo.uid + " for provider "
10398 + name + ": user " + userId + " is stopped");
10402 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10403 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10404 cpr = mProviderMap.getProviderByClass(comp, userId);
10405 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10406 final boolean firstClass = cpr == null;
10408 final long ident = Binder.clearCallingIdentity();
10410 // If permissions need a review before any of the app components can run,
10411 // we return no provider and launch a review activity if the calling app
10412 // is in the foreground.
10413 if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10414 if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10420 checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10421 ApplicationInfo ai =
10422 AppGlobals.getPackageManager().
10423 getApplicationInfo(
10424 cpi.applicationInfo.packageName,
10425 STOCK_PM_FLAGS, userId);
10426 checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10428 Slog.w(TAG, "No package info for content provider "
10432 ai = getAppInfoForUser(ai, userId);
10433 cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10434 } catch (RemoteException ex) {
10435 // pm is in same process, this will never happen.
10437 Binder.restoreCallingIdentity(ident);
10441 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10443 if (r != null && cpr.canRunHere(r)) {
10444 // If this is a multiprocess provider, then just return its
10445 // info and allow the caller to instantiate it. Only do
10446 // this if the provider is the same user as the caller's
10447 // process, or can run as root (so can be in any process).
10448 return cpr.newHolder(null);
10451 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10452 + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10453 + cpr.info.name + " callers=" + Debug.getCallers(6));
10455 // This is single process, and our app is now connecting to it.
10456 // See if we are already in the process of launching this
10458 final int N = mLaunchingProviders.size();
10460 for (i = 0; i < N; i++) {
10461 if (mLaunchingProviders.get(i) == cpr) {
10466 // If the provider is not already being launched, then get it
10469 final long origId = Binder.clearCallingIdentity();
10472 // Content provider is now in use, its package can't be stopped.
10474 checkTime(startTime, "getContentProviderImpl: before set stopped state");
10475 AppGlobals.getPackageManager().setPackageStoppedState(
10476 cpr.appInfo.packageName, false, userId);
10477 checkTime(startTime, "getContentProviderImpl: after set stopped state");
10478 } catch (RemoteException e) {
10479 } catch (IllegalArgumentException e) {
10480 Slog.w(TAG, "Failed trying to unstop package "
10481 + cpr.appInfo.packageName + ": " + e);
10484 // Use existing process if already started
10485 checkTime(startTime, "getContentProviderImpl: looking for process record");
10486 ProcessRecord proc = getProcessRecordLocked(
10487 cpi.processName, cpr.appInfo.uid, false);
10488 if (proc != null && proc.thread != null) {
10489 if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10490 "Installing in existing process " + proc);
10491 if (!proc.pubProviders.containsKey(cpi.name)) {
10492 checkTime(startTime, "getContentProviderImpl: scheduling install");
10493 proc.pubProviders.put(cpi.name, cpr);
10495 proc.thread.scheduleInstallProvider(cpi);
10496 } catch (RemoteException e) {
10500 checkTime(startTime, "getContentProviderImpl: before start process");
10501 proc = startProcessLocked(cpi.processName,
10502 cpr.appInfo, false, 0, "content provider",
10503 new ComponentName(cpi.applicationInfo.packageName,
10504 cpi.name), false, false, false);
10505 checkTime(startTime, "getContentProviderImpl: after start process");
10506 if (proc == null) {
10507 Slog.w(TAG, "Unable to launch app "
10508 + cpi.applicationInfo.packageName + "/"
10509 + cpi.applicationInfo.uid + " for provider "
10510 + name + ": process is bad");
10514 cpr.launchingApp = proc;
10515 mLaunchingProviders.add(cpr);
10517 Binder.restoreCallingIdentity(origId);
10521 checkTime(startTime, "getContentProviderImpl: updating data structures");
10523 // Make sure the provider is published (the same provider class
10524 // may be published under multiple names).
10526 mProviderMap.putProviderByClass(comp, cpr);
10529 mProviderMap.putProviderByName(name, cpr);
10530 conn = incProviderCountLocked(r, cpr, token, stable);
10531 if (conn != null) {
10532 conn.waiting = true;
10535 checkTime(startTime, "getContentProviderImpl: done!");
10538 // Wait for the provider to be published...
10539 synchronized (cpr) {
10540 while (cpr.provider == null) {
10541 if (cpr.launchingApp == null) {
10542 Slog.w(TAG, "Unable to launch app "
10543 + cpi.applicationInfo.packageName + "/"
10544 + cpi.applicationInfo.uid + " for provider "
10545 + name + ": launching app became null");
10546 EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10547 UserHandle.getUserId(cpi.applicationInfo.uid),
10548 cpi.applicationInfo.packageName,
10549 cpi.applicationInfo.uid, name);
10553 if (DEBUG_MU) Slog.v(TAG_MU,
10554 "Waiting to start provider " + cpr
10555 + " launchingApp=" + cpr.launchingApp);
10556 if (conn != null) {
10557 conn.waiting = true;
10560 } catch (InterruptedException ex) {
10562 if (conn != null) {
10563 conn.waiting = false;
10568 return cpr != null ? cpr.newHolder(conn) : null;
10571 private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10572 ProcessRecord r, final int userId) {
10573 if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10574 cpi.packageName, r.userId)) {
10576 final boolean callerForeground = r != null ? r.setSchedGroup
10577 != ProcessList.SCHED_GROUP_BACKGROUND : true;
10579 // Show a permission review UI only for starting from a foreground app
10580 if (!callerForeground) {
10581 Slog.w(TAG, "u" + r.userId + " Instantiating a provider in package"
10582 + cpi.packageName + " requires a permissions review");
10586 final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10587 intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10588 | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10589 intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10591 if (DEBUG_PERMISSIONS_REVIEW) {
10592 Slog.i(TAG, "u" + r.userId + " Launching permission review "
10593 + "for package " + cpi.packageName);
10596 final UserHandle userHandle = new UserHandle(userId);
10597 mHandler.post(new Runnable() {
10599 public void run() {
10600 mContext.startActivityAsUser(intent, userHandle);
10610 PackageManagerInternal getPackageManagerInternalLocked() {
10611 if (mPackageManagerInt == null) {
10612 mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10614 return mPackageManagerInt;
10618 public final ContentProviderHolder getContentProvider(
10619 IApplicationThread caller, String name, int userId, boolean stable) {
10620 enforceNotIsolatedCaller("getContentProvider");
10621 if (caller == null) {
10622 String msg = "null IApplicationThread when getting content provider "
10625 throw new SecurityException(msg);
10627 // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
10628 // with cross-user grant.
10629 return getContentProviderImpl(caller, name, null, stable, userId);
10632 public ContentProviderHolder getContentProviderExternal(
10633 String name, int userId, IBinder token) {
10634 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10635 "Do not have permission in call getContentProviderExternal()");
10636 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
10637 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
10638 return getContentProviderExternalUnchecked(name, token, userId);
10641 private ContentProviderHolder getContentProviderExternalUnchecked(String name,
10642 IBinder token, int userId) {
10643 return getContentProviderImpl(null, name, token, true, userId);
10647 * Drop a content provider from a ProcessRecord's bookkeeping
10649 public void removeContentProvider(IBinder connection, boolean stable) {
10650 enforceNotIsolatedCaller("removeContentProvider");
10651 long ident = Binder.clearCallingIdentity();
10653 synchronized (this) {
10654 ContentProviderConnection conn;
10656 conn = (ContentProviderConnection)connection;
10657 } catch (ClassCastException e) {
10658 String msg ="removeContentProvider: " + connection
10659 + " not a ContentProviderConnection";
10661 throw new IllegalArgumentException(msg);
10663 if (conn == null) {
10664 throw new NullPointerException("connection is null");
10666 if (decProviderCountLocked(conn, null, null, stable)) {
10667 updateOomAdjLocked();
10671 Binder.restoreCallingIdentity(ident);
10675 public void removeContentProviderExternal(String name, IBinder token) {
10676 enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
10677 "Do not have permission in call removeContentProviderExternal()");
10678 int userId = UserHandle.getCallingUserId();
10679 long ident = Binder.clearCallingIdentity();
10681 removeContentProviderExternalUnchecked(name, token, userId);
10683 Binder.restoreCallingIdentity(ident);
10687 private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
10688 synchronized (this) {
10689 ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
10691 //remove from mProvidersByClass
10692 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
10696 //update content provider record entry info
10697 ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
10698 ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
10699 if (localCpr.hasExternalProcessHandles()) {
10700 if (localCpr.removeExternalProcessHandleLocked(token)) {
10701 updateOomAdjLocked();
10703 Slog.e(TAG, "Attmpt to remove content provider " + localCpr
10704 + " with no external reference for token: "
10708 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
10709 + " with no external references.");
10714 public final void publishContentProviders(IApplicationThread caller,
10715 List<ContentProviderHolder> providers) {
10716 if (providers == null) {
10720 enforceNotIsolatedCaller("publishContentProviders");
10721 synchronized (this) {
10722 final ProcessRecord r = getRecordForAppLocked(caller);
10723 if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
10725 throw new SecurityException(
10726 "Unable to find app for caller " + caller
10727 + " (pid=" + Binder.getCallingPid()
10728 + ") when publishing content providers");
10731 final long origId = Binder.clearCallingIdentity();
10733 final int N = providers.size();
10734 for (int i = 0; i < N; i++) {
10735 ContentProviderHolder src = providers.get(i);
10736 if (src == null || src.info == null || src.provider == null) {
10739 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
10740 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
10742 ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
10743 mProviderMap.putProviderByClass(comp, dst);
10744 String names[] = dst.info.authority.split(";");
10745 for (int j = 0; j < names.length; j++) {
10746 mProviderMap.putProviderByName(names[j], dst);
10749 int launchingCount = mLaunchingProviders.size();
10751 boolean wasInLaunchingProviders = false;
10752 for (j = 0; j < launchingCount; j++) {
10753 if (mLaunchingProviders.get(j) == dst) {
10754 mLaunchingProviders.remove(j);
10755 wasInLaunchingProviders = true;
10760 if (wasInLaunchingProviders) {
10761 mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
10763 synchronized (dst) {
10764 dst.provider = src.provider;
10768 updateOomAdjLocked(r);
10769 maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
10770 src.info.authority);
10774 Binder.restoreCallingIdentity(origId);
10778 public boolean refContentProvider(IBinder connection, int stable, int unstable) {
10779 ContentProviderConnection conn;
10781 conn = (ContentProviderConnection)connection;
10782 } catch (ClassCastException e) {
10783 String msg ="refContentProvider: " + connection
10784 + " not a ContentProviderConnection";
10786 throw new IllegalArgumentException(msg);
10788 if (conn == null) {
10789 throw new NullPointerException("connection is null");
10792 synchronized (this) {
10794 conn.numStableIncs += stable;
10796 stable = conn.stableCount + stable;
10798 throw new IllegalStateException("stableCount < 0: " + stable);
10801 if (unstable > 0) {
10802 conn.numUnstableIncs += unstable;
10804 unstable = conn.unstableCount + unstable;
10805 if (unstable < 0) {
10806 throw new IllegalStateException("unstableCount < 0: " + unstable);
10809 if ((stable+unstable) <= 0) {
10810 throw new IllegalStateException("ref counts can't go to zero here: stable="
10811 + stable + " unstable=" + unstable);
10813 conn.stableCount = stable;
10814 conn.unstableCount = unstable;
10819 public void unstableProviderDied(IBinder connection) {
10820 ContentProviderConnection conn;
10822 conn = (ContentProviderConnection)connection;
10823 } catch (ClassCastException e) {
10824 String msg ="refContentProvider: " + connection
10825 + " not a ContentProviderConnection";
10827 throw new IllegalArgumentException(msg);
10829 if (conn == null) {
10830 throw new NullPointerException("connection is null");
10833 // Safely retrieve the content provider associated with the connection.
10834 IContentProvider provider;
10835 synchronized (this) {
10836 provider = conn.provider.provider;
10839 if (provider == null) {
10840 // Um, yeah, we're way ahead of you.
10844 // Make sure the caller is being honest with us.
10845 if (provider.asBinder().pingBinder()) {
10846 // Er, no, still looks good to us.
10847 synchronized (this) {
10848 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
10849 + " says " + conn + " died, but we don't agree");
10854 // Well look at that! It's dead!
10855 synchronized (this) {
10856 if (conn.provider.provider != provider) {
10857 // But something changed... good enough.
10861 ProcessRecord proc = conn.provider.proc;
10862 if (proc == null || proc.thread == null) {
10863 // Seems like the process is already cleaned up.
10867 // As far as we're concerned, this is just like receiving a
10868 // death notification... just a bit prematurely.
10869 Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
10870 + ") early provider death");
10871 final long ident = Binder.clearCallingIdentity();
10873 appDiedLocked(proc);
10875 Binder.restoreCallingIdentity(ident);
10881 public void appNotRespondingViaProvider(IBinder connection) {
10882 enforceCallingPermission(
10883 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
10885 final ContentProviderConnection conn = (ContentProviderConnection) connection;
10886 if (conn == null) {
10887 Slog.w(TAG, "ContentProviderConnection is null");
10891 final ProcessRecord host = conn.provider.proc;
10892 if (host == null) {
10893 Slog.w(TAG, "Failed to find hosting ProcessRecord");
10897 mHandler.post(new Runnable() {
10899 public void run() {
10900 mAppErrors.appNotResponding(host, null, null, false,
10901 "ContentProvider not responding");
10906 public final void installSystemProviders() {
10907 List<ProviderInfo> providers;
10908 synchronized (this) {
10909 ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
10910 providers = generateApplicationProvidersLocked(app);
10911 if (providers != null) {
10912 for (int i=providers.size()-1; i>=0; i--) {
10913 ProviderInfo pi = (ProviderInfo)providers.get(i);
10914 if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
10915 Slog.w(TAG, "Not installing system proc provider " + pi.name
10916 + ": not system .apk");
10917 providers.remove(i);
10922 if (providers != null) {
10923 mSystemThread.installSystemProviders(providers);
10926 mCoreSettingsObserver = new CoreSettingsObserver(this);
10927 mFontScaleSettingObserver = new FontScaleSettingObserver();
10929 //mUsageStatsService.monitorPackages();
10932 private void startPersistentApps(int matchFlags) {
10933 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
10935 synchronized (this) {
10937 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
10938 .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
10939 for (ApplicationInfo app : apps) {
10940 if (!"android".equals(app.packageName)) {
10941 addAppLocked(app, false, null /* ABI override */);
10944 } catch (RemoteException ex) {
10950 * When a user is unlocked, we need to install encryption-unaware providers
10951 * belonging to any running apps.
10953 private void installEncryptionUnawareProviders(int userId) {
10954 if (!StorageManager.isFileEncryptedNativeOrEmulated()) {
10955 // TODO: eventually pivot this back to look at current user state,
10956 // similar to the comment in UserManager.isUserUnlocked(), but for
10957 // now, if we started apps when "unlocked" then unaware providers
10958 // have already been spun up.
10962 // We're only interested in providers that are encryption unaware, and
10963 // we don't care about uninstalled apps, since there's no way they're
10964 // running at this point.
10965 final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
10967 synchronized (this) {
10968 final int NP = mProcessNames.getMap().size();
10969 for (int ip = 0; ip < NP; ip++) {
10970 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
10971 final int NA = apps.size();
10972 for (int ia = 0; ia < NA; ia++) {
10973 final ProcessRecord app = apps.valueAt(ia);
10974 if (app.userId != userId || app.thread == null) continue;
10976 final int NG = app.pkgList.size();
10977 for (int ig = 0; ig < NG; ig++) {
10979 final String pkgName = app.pkgList.keyAt(ig);
10980 final PackageInfo pkgInfo = AppGlobals.getPackageManager()
10981 .getPackageInfo(pkgName, matchFlags, userId);
10982 if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
10983 for (ProviderInfo provInfo : pkgInfo.providers) {
10984 Log.v(TAG, "Installing " + provInfo);
10985 app.thread.scheduleInstallProvider(provInfo);
10988 } catch (RemoteException ignored) {
10997 * Allows apps to retrieve the MIME type of a URI.
10998 * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
10999 * users, then it does not need permission to access the ContentProvider.
11000 * Either, it needs cross-user uri grants.
11002 * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11004 * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11005 * src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11007 public String getProviderMimeType(Uri uri, int userId) {
11008 enforceNotIsolatedCaller("getProviderMimeType");
11009 final String name = uri.getAuthority();
11010 int callingUid = Binder.getCallingUid();
11011 int callingPid = Binder.getCallingPid();
11013 boolean clearedIdentity = false;
11014 synchronized (this) {
11015 userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11017 if (canClearIdentity(callingPid, callingUid, userId)) {
11018 clearedIdentity = true;
11019 ident = Binder.clearCallingIdentity();
11021 ContentProviderHolder holder = null;
11023 holder = getContentProviderExternalUnchecked(name, null, userId);
11024 if (holder != null) {
11025 return holder.provider.getType(uri);
11027 } catch (RemoteException e) {
11028 Log.w(TAG, "Content provider dead retrieving " + uri, e);
11031 // We need to clear the identity to call removeContentProviderExternalUnchecked
11032 if (!clearedIdentity) {
11033 ident = Binder.clearCallingIdentity();
11036 if (holder != null) {
11037 removeContentProviderExternalUnchecked(name, null, userId);
11040 Binder.restoreCallingIdentity(ident);
11047 private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11048 if (UserHandle.getUserId(callingUid) == userId) {
11051 if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11052 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11053 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11054 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11060 // =========================================================
11061 // GLOBAL MANAGEMENT
11062 // =========================================================
11064 final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11065 boolean isolated, int isolatedUid) {
11066 String proc = customProcess != null ? customProcess : info.processName;
11067 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11068 final int userId = UserHandle.getUserId(info.uid);
11069 int uid = info.uid;
11071 if (isolatedUid == 0) {
11072 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11074 if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11075 || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11076 mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11078 uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11079 mNextIsolatedProcessUid++;
11080 if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11081 // No process for this uid, use it.
11085 if (stepsLeft <= 0) {
11090 // Special case for startIsolatedProcess (internal only), where
11091 // the uid of the isolated process is specified by the caller.
11095 final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11096 if (!mBooted && !mBooting
11097 && userId == UserHandle.USER_SYSTEM
11098 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11099 r.persistent = true;
11101 addProcessNameLocked(r);
11105 final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11106 String abiOverride) {
11109 app = getProcessRecordLocked(info.processName, info.uid, true);
11115 app = newProcessRecordLocked(info, null, isolated, 0);
11116 updateLruProcessLocked(app, false, null);
11117 updateOomAdjLocked();
11120 // This package really, really can not be stopped.
11122 AppGlobals.getPackageManager().setPackageStoppedState(
11123 info.packageName, false, UserHandle.getUserId(app.uid));
11124 } catch (RemoteException e) {
11125 } catch (IllegalArgumentException e) {
11126 Slog.w(TAG, "Failed trying to unstop package "
11127 + info.packageName + ": " + e);
11130 if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11131 app.persistent = true;
11132 app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11134 if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11135 mPersistentStartingProcesses.add(app);
11136 startProcessLocked(app, "added application", app.processName, abiOverride,
11137 null /* entryPoint */, null /* entryPointArgs */);
11143 public void unhandledBack() {
11144 enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11145 "unhandledBack()");
11147 synchronized(this) {
11148 final long origId = Binder.clearCallingIdentity();
11150 getFocusedStack().unhandledBackLocked();
11152 Binder.restoreCallingIdentity(origId);
11157 public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11158 enforceNotIsolatedCaller("openContentUri");
11159 final int userId = UserHandle.getCallingUserId();
11160 String name = uri.getAuthority();
11161 ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11162 ParcelFileDescriptor pfd = null;
11164 // We record the binder invoker's uid in thread-local storage before
11165 // going to the content provider to open the file. Later, in the code
11166 // that handles all permissions checks, we look for this uid and use
11167 // that rather than the Activity Manager's own uid. The effect is that
11168 // we do the check against the caller's permissions even though it looks
11169 // to the content provider like the Activity Manager itself is making
11171 Binder token = new Binder();
11172 sCallerIdentity.set(new Identity(
11173 token, Binder.getCallingPid(), Binder.getCallingUid()));
11175 pfd = cph.provider.openFile(null, uri, "r", null, token);
11176 } catch (FileNotFoundException e) {
11177 // do nothing; pfd will be returned null
11179 // Ensure that whatever happens, we clean up the identity state
11180 sCallerIdentity.remove();
11181 // Ensure we're done with the provider.
11182 removeContentProviderExternalUnchecked(name, null, userId);
11185 Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11190 // Actually is sleeping or shutting down or whatever else in the future
11191 // is an inactive state.
11192 public boolean isSleepingOrShuttingDown() {
11193 return isSleeping() || mShuttingDown;
11196 public boolean isSleeping() {
11200 void onWakefulnessChanged(int wakefulness) {
11201 synchronized(this) {
11202 mWakefulness = wakefulness;
11203 updateSleepIfNeededLocked();
11207 void finishRunningVoiceLocked() {
11208 if (mRunningVoice != null) {
11209 mRunningVoice = null;
11210 mVoiceWakeLock.release();
11211 updateSleepIfNeededLocked();
11215 void startTimeTrackingFocusedActivityLocked() {
11216 if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11217 mCurAppTimeTracker.start(mFocusedActivity.packageName);
11221 void updateSleepIfNeededLocked() {
11222 if (mSleeping && !shouldSleepLocked()) {
11224 startTimeTrackingFocusedActivityLocked();
11225 mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11226 mStackSupervisor.comeOutOfSleepIfNeededLocked();
11227 updateOomAdjLocked();
11228 } else if (!mSleeping && shouldSleepLocked()) {
11230 if (mCurAppTimeTracker != null) {
11231 mCurAppTimeTracker.stop();
11233 mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11234 mStackSupervisor.goingToSleepLocked();
11235 updateOomAdjLocked();
11237 // Initialize the wake times of all processes.
11238 checkExcessivePowerUsageLocked(false);
11239 mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11240 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11241 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11245 private boolean shouldSleepLocked() {
11246 // Resume applications while running a voice interactor.
11247 if (mRunningVoice != null) {
11251 // TODO: Transform the lock screen state into a sleep token instead.
11252 switch (mWakefulness) {
11253 case PowerManagerInternal.WAKEFULNESS_AWAKE:
11254 case PowerManagerInternal.WAKEFULNESS_DREAMING:
11255 case PowerManagerInternal.WAKEFULNESS_DOZING:
11256 // Pause applications whenever the lock screen is shown or any sleep
11257 // tokens have been acquired.
11258 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11259 case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11261 // If we're asleep then pause applications unconditionally.
11266 /** Pokes the task persister. */
11267 void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11268 mRecentTasks.notifyTaskPersisterLocked(task, flush);
11271 /** Notifies all listeners when the task stack has changed. */
11272 void notifyTaskStackChangedLocked() {
11273 mHandler.sendEmptyMessage(LOG_STACK_STATE);
11274 mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11275 Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11276 mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11279 /** Notifies all listeners when an Activity is pinned. */
11280 void notifyActivityPinnedLocked() {
11281 mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11282 mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11286 * Notifies all listeners when an attempt was made to start an an activity that is already
11287 * running in the pinned stack and the activity was not actually started, but the task is
11288 * either brought to the front or a new Intent is delivered to it.
11290 void notifyPinnedActivityRestartAttemptLocked() {
11291 mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11292 mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11295 /** Notifies all listeners when the pinned stack animation ends. */
11297 public void notifyPinnedStackAnimationEnded() {
11298 synchronized (this) {
11299 mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11300 mHandler.obtainMessage(
11301 NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11306 public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11307 mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11311 public boolean shutdown(int timeout) {
11312 if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11313 != PackageManager.PERMISSION_GRANTED) {
11314 throw new SecurityException("Requires permission "
11315 + android.Manifest.permission.SHUTDOWN);
11318 boolean timedout = false;
11320 synchronized(this) {
11321 mShuttingDown = true;
11322 updateEventDispatchingLocked();
11323 timedout = mStackSupervisor.shutdownLocked(timeout);
11326 mAppOpsService.shutdown();
11327 if (mUsageStatsService != null) {
11328 mUsageStatsService.prepareShutdown();
11330 mBatteryStatsService.shutdown();
11331 synchronized (this) {
11332 mProcessStats.shutdownLocked();
11333 notifyTaskPersisterLocked(null, true);
11339 public final void activitySlept(IBinder token) {
11340 if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11342 final long origId = Binder.clearCallingIdentity();
11344 synchronized (this) {
11345 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11347 mStackSupervisor.activitySleptLocked(r);
11351 Binder.restoreCallingIdentity(origId);
11354 private String lockScreenShownToString() {
11355 switch (mLockScreenShown) {
11356 case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11357 case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11358 case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11359 default: return "Unknown=" + mLockScreenShown;
11363 void logLockScreen(String msg) {
11364 if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11365 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11366 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11367 + " mSleeping=" + mSleeping);
11370 void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11371 Slog.d(TAG, "<<< startRunningVoiceLocked()");
11372 mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11373 if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11374 boolean wasRunningVoice = mRunningVoice != null;
11375 mRunningVoice = session;
11376 if (!wasRunningVoice) {
11377 mVoiceWakeLock.acquire();
11378 updateSleepIfNeededLocked();
11383 private void updateEventDispatchingLocked() {
11384 mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11387 public void setLockScreenShown(boolean shown) {
11388 if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11389 != PackageManager.PERMISSION_GRANTED) {
11390 throw new SecurityException("Requires permission "
11391 + android.Manifest.permission.DEVICE_POWER);
11394 synchronized(this) {
11395 long ident = Binder.clearCallingIdentity();
11397 if (DEBUG_LOCKSCREEN) logLockScreen(" shown=" + shown);
11398 mLockScreenShown = shown ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11399 updateSleepIfNeededLocked();
11401 Binder.restoreCallingIdentity(ident);
11407 public void notifyLockedProfile(@UserIdInt int userId) {
11409 if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11410 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11412 } catch (RemoteException ex) {
11413 throw new SecurityException("Fail to check is caller a privileged app", ex);
11416 synchronized (this) {
11417 if (mStackSupervisor.isFocusedUserLockedProfile()) {
11418 final long ident = Binder.clearCallingIdentity();
11420 final int currentUserId = mUserController.getCurrentUserIdLocked();
11421 startHomeActivityLocked(currentUserId, "notifyProfileLocked");
11423 Binder.restoreCallingIdentity(ident);
11430 public void stopAppSwitches() {
11431 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11432 != PackageManager.PERMISSION_GRANTED) {
11433 throw new SecurityException("viewquires permission "
11434 + android.Manifest.permission.STOP_APP_SWITCHES);
11437 synchronized(this) {
11438 mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11439 + APP_SWITCH_DELAY_TIME;
11440 mDidAppSwitch = false;
11441 mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11442 Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11443 mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11447 public void resumeAppSwitches() {
11448 if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11449 != PackageManager.PERMISSION_GRANTED) {
11450 throw new SecurityException("Requires permission "
11451 + android.Manifest.permission.STOP_APP_SWITCHES);
11454 synchronized(this) {
11455 // Note that we don't execute any pending app switches... we will
11456 // let those wait until either the timeout, or the next start
11457 // activity request.
11458 mAppSwitchesAllowedTime = 0;
11462 boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11463 int callingPid, int callingUid, String name) {
11464 if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11468 int perm = checkComponentPermission(
11469 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11470 sourceUid, -1, true);
11471 if (perm == PackageManager.PERMISSION_GRANTED) {
11475 // If the actual IPC caller is different from the logical source, then
11476 // also see if they are allowed to control app switches.
11477 if (callingUid != -1 && callingUid != sourceUid) {
11478 perm = checkComponentPermission(
11479 android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11480 callingUid, -1, true);
11481 if (perm == PackageManager.PERMISSION_GRANTED) {
11486 Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11490 public void setDebugApp(String packageName, boolean waitForDebugger,
11491 boolean persistent) {
11492 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11495 long ident = Binder.clearCallingIdentity();
11497 // Note that this is not really thread safe if there are multiple
11498 // callers into it at the same time, but that's not a situation we
11501 final ContentResolver resolver = mContext.getContentResolver();
11502 Settings.Global.putString(
11503 resolver, Settings.Global.DEBUG_APP,
11505 Settings.Global.putInt(
11506 resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11507 waitForDebugger ? 1 : 0);
11510 synchronized (this) {
11512 mOrigDebugApp = mDebugApp;
11513 mOrigWaitForDebugger = mWaitForDebugger;
11515 mDebugApp = packageName;
11516 mWaitForDebugger = waitForDebugger;
11517 mDebugTransient = !persistent;
11518 if (packageName != null) {
11519 forceStopPackageLocked(packageName, -1, false, false, true, true,
11520 false, UserHandle.USER_ALL, "set debug app");
11524 Binder.restoreCallingIdentity(ident);
11528 void setTrackAllocationApp(ApplicationInfo app, String processName) {
11529 synchronized (this) {
11530 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11531 if (!isDebuggable) {
11532 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11533 throw new SecurityException("Process not debuggable: " + app.packageName);
11537 mTrackAllocationApp = processName;
11541 void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11542 synchronized (this) {
11543 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11544 if (!isDebuggable) {
11545 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11546 throw new SecurityException("Process not debuggable: " + app.packageName);
11549 mProfileApp = processName;
11550 mProfileFile = profilerInfo.profileFile;
11551 if (mProfileFd != null) {
11553 mProfileFd.close();
11554 } catch (IOException e) {
11558 mProfileFd = profilerInfo.profileFd;
11559 mSamplingInterval = profilerInfo.samplingInterval;
11560 mAutoStopProfiler = profilerInfo.autoStopProfiler;
11565 void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
11566 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11567 if (!isDebuggable) {
11568 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11569 throw new SecurityException("Process not debuggable: " + app.packageName);
11572 mNativeDebuggingApp = processName;
11576 public void setAlwaysFinish(boolean enabled) {
11577 enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
11578 "setAlwaysFinish()");
11580 long ident = Binder.clearCallingIdentity();
11582 Settings.Global.putInt(
11583 mContext.getContentResolver(),
11584 Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
11586 synchronized (this) {
11587 mAlwaysFinishActivities = enabled;
11590 Binder.restoreCallingIdentity(ident);
11595 public void setLenientBackgroundCheck(boolean enabled) {
11596 enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
11597 "setLenientBackgroundCheck()");
11599 long ident = Binder.clearCallingIdentity();
11601 Settings.Global.putInt(
11602 mContext.getContentResolver(),
11603 Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
11605 synchronized (this) {
11606 mLenientBackgroundCheck = enabled;
11609 Binder.restoreCallingIdentity(ident);
11614 public void setActivityController(IActivityController controller, boolean imAMonkey) {
11615 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11616 "setActivityController()");
11617 synchronized (this) {
11618 mController = controller;
11619 mControllerIsAMonkey = imAMonkey;
11620 Watchdog.getInstance().setActivityController(controller);
11625 public void setUserIsMonkey(boolean userIsMonkey) {
11626 synchronized (this) {
11627 synchronized (mPidsSelfLocked) {
11628 final int callingPid = Binder.getCallingPid();
11629 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
11630 if (precessRecord == null) {
11631 throw new SecurityException("Unknown process: " + callingPid);
11633 if (precessRecord.instrumentationUiAutomationConnection == null) {
11634 throw new SecurityException("Only an instrumentation process "
11635 + "with a UiAutomation can call setUserIsMonkey");
11638 mUserIsMonkey = userIsMonkey;
11643 public boolean isUserAMonkey() {
11644 synchronized (this) {
11645 // If there is a controller also implies the user is a monkey.
11646 return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
11650 public void requestBugReport(int bugreportType) {
11651 String service = null;
11652 switch (bugreportType) {
11653 case ActivityManager.BUGREPORT_OPTION_FULL:
11654 service = "bugreport";
11656 case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
11657 service = "bugreportplus";
11659 case ActivityManager.BUGREPORT_OPTION_REMOTE:
11660 service = "bugreportremote";
11663 if (service == null) {
11664 throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
11667 enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
11668 SystemProperties.set("ctl.start", service);
11671 public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
11672 return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
11675 public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
11676 if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
11677 return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
11679 return KEY_DISPATCHING_TIMEOUT;
11683 public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
11684 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11685 != PackageManager.PERMISSION_GRANTED) {
11686 throw new SecurityException("Requires permission "
11687 + android.Manifest.permission.FILTER_EVENTS);
11689 ProcessRecord proc;
11691 synchronized (this) {
11692 synchronized (mPidsSelfLocked) {
11693 proc = mPidsSelfLocked.get(pid);
11695 timeout = getInputDispatchingTimeoutLocked(proc);
11698 if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
11706 * Handle input dispatching timeouts.
11707 * Returns whether input dispatching should be aborted or not.
11709 public boolean inputDispatchingTimedOut(final ProcessRecord proc,
11710 final ActivityRecord activity, final ActivityRecord parent,
11711 final boolean aboveSystem, String reason) {
11712 if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
11713 != PackageManager.PERMISSION_GRANTED) {
11714 throw new SecurityException("Requires permission "
11715 + android.Manifest.permission.FILTER_EVENTS);
11718 final String annotation;
11719 if (reason == null) {
11720 annotation = "Input dispatching timed out";
11722 annotation = "Input dispatching timed out (" + reason + ")";
11725 if (proc != null) {
11726 synchronized (this) {
11727 if (proc.debugging) {
11732 // Give more time since we were dexopting.
11733 mDidDexOpt = false;
11737 if (proc.instrumentationClass != null) {
11738 Bundle info = new Bundle();
11739 info.putString("shortMsg", "keyDispatchingTimedOut");
11740 info.putString("longMsg", annotation);
11741 finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
11745 mHandler.post(new Runnable() {
11747 public void run() {
11748 mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
11757 public Bundle getAssistContextExtras(int requestType) {
11758 PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
11759 null, UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
11763 synchronized (pae) {
11764 while (!pae.haveResult) {
11767 } catch (InterruptedException e) {
11771 synchronized (this) {
11772 buildAssistBundleLocked(pae, pae.result);
11773 mPendingAssistExtras.remove(pae);
11774 mUiHandler.removeCallbacks(pae);
11780 public boolean isAssistDataAllowedOnCurrentActivity() {
11782 synchronized (this) {
11783 userId = mUserController.getCurrentUserIdLocked();
11784 ActivityRecord activity = getFocusedStack().topActivity();
11785 if (activity == null) {
11788 userId = activity.userId;
11790 DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
11791 Context.DEVICE_POLICY_SERVICE);
11792 return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
11796 public boolean showAssistFromActivity(IBinder token, Bundle args) {
11797 long ident = Binder.clearCallingIdentity();
11799 synchronized (this) {
11800 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
11801 ActivityRecord top = getFocusedStack().topActivity();
11802 if (top != caller) {
11803 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11804 + " is not current top " + top);
11807 if (!top.nowVisible) {
11808 Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
11809 + " is not visible");
11813 AssistUtils utils = new AssistUtils(mContext);
11814 return utils.showSessionForActiveService(args,
11815 VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
11817 Binder.restoreCallingIdentity(ident);
11822 public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
11823 IBinder activityToken) {
11824 return enqueueAssistContext(requestType, null, null, receiver, activityToken,
11825 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT) != null;
11828 private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
11829 IResultReceiver receiver, IBinder activityToken, int userHandle, Bundle args,
11831 enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
11832 "enqueueAssistContext()");
11833 synchronized (this) {
11834 ActivityRecord activity = getFocusedStack().topActivity();
11835 if (activity == null) {
11836 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
11839 if (activity.app == null || activity.app.thread == null) {
11840 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
11843 if (activityToken != null) {
11844 ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
11845 if (activity != caller) {
11846 Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
11847 + " is not current top " + activity);
11851 PendingAssistExtras pae;
11852 Bundle extras = new Bundle();
11853 if (args != null) {
11854 extras.putAll(args);
11856 extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
11857 extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
11858 pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, userHandle);
11860 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
11862 mPendingAssistExtras.add(pae);
11863 mUiHandler.postDelayed(pae, timeout);
11864 } catch (RemoteException e) {
11865 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
11872 void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
11873 IResultReceiver receiver;
11874 synchronized (this) {
11875 mPendingAssistExtras.remove(pae);
11876 receiver = pae.receiver;
11878 if (receiver != null) {
11879 // Caller wants result sent back to them.
11881 pae.receiver.send(0, null);
11882 } catch (RemoteException e) {
11887 private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
11888 if (result != null) {
11889 pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
11891 if (pae.hint != null) {
11892 pae.extras.putBoolean(pae.hint, true);
11896 public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
11897 AssistContent content, Uri referrer) {
11898 PendingAssistExtras pae = (PendingAssistExtras)token;
11899 synchronized (pae) {
11900 pae.result = extras;
11901 pae.structure = structure;
11902 pae.content = content;
11903 if (referrer != null) {
11904 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
11906 pae.haveResult = true;
11908 if (pae.intent == null && pae.receiver == null) {
11909 // Caller is just waiting for the result.
11914 // We are now ready to launch the assist activity.
11915 IResultReceiver sendReceiver = null;
11916 Bundle sendBundle = null;
11917 synchronized (this) {
11918 buildAssistBundleLocked(pae, extras);
11919 boolean exists = mPendingAssistExtras.remove(pae);
11920 mUiHandler.removeCallbacks(pae);
11925 if ((sendReceiver=pae.receiver) != null) {
11926 // Caller wants result sent back to them.
11927 sendBundle = new Bundle();
11928 sendBundle.putBundle("data", pae.extras);
11929 sendBundle.putParcelable("structure", pae.structure);
11930 sendBundle.putParcelable("content", pae.content);
11933 if (sendReceiver != null) {
11935 sendReceiver.send(0, sendBundle);
11936 } catch (RemoteException e) {
11941 long ident = Binder.clearCallingIdentity();
11943 pae.intent.replaceExtras(pae.extras);
11944 pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11945 | Intent.FLAG_ACTIVITY_SINGLE_TOP
11946 | Intent.FLAG_ACTIVITY_CLEAR_TOP);
11947 closeSystemDialogs("assist");
11949 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
11950 } catch (ActivityNotFoundException e) {
11951 Slog.w(TAG, "No activity to handle assist action.", e);
11954 Binder.restoreCallingIdentity(ident);
11958 public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
11960 return enqueueAssistContext(requestType, intent, hint, null, null, userHandle, args,
11961 PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
11964 public void registerProcessObserver(IProcessObserver observer) {
11965 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11966 "registerProcessObserver()");
11967 synchronized (this) {
11968 mProcessObservers.register(observer);
11973 public void unregisterProcessObserver(IProcessObserver observer) {
11974 synchronized (this) {
11975 mProcessObservers.unregister(observer);
11980 public void registerUidObserver(IUidObserver observer, int which) {
11981 enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
11982 "registerUidObserver()");
11983 synchronized (this) {
11984 mUidObservers.register(observer, which);
11989 public void unregisterUidObserver(IUidObserver observer) {
11990 synchronized (this) {
11991 mUidObservers.unregister(observer);
11996 public boolean convertFromTranslucent(IBinder token) {
11997 final long origId = Binder.clearCallingIdentity();
11999 synchronized (this) {
12000 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12004 final boolean translucentChanged = r.changeWindowTranslucency(true);
12005 if (translucentChanged) {
12006 r.task.stack.releaseBackgroundResources(r);
12007 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12009 mWindowManager.setAppFullscreen(token, true);
12010 return translucentChanged;
12013 Binder.restoreCallingIdentity(origId);
12018 public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12019 final long origId = Binder.clearCallingIdentity();
12021 synchronized (this) {
12022 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12026 int index = r.task.mActivities.lastIndexOf(r);
12028 ActivityRecord under = r.task.mActivities.get(index - 1);
12029 under.returningOptions = options;
12031 final boolean translucentChanged = r.changeWindowTranslucency(false);
12032 if (translucentChanged) {
12033 r.task.stack.convertActivityToTranslucent(r);
12035 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12036 mWindowManager.setAppFullscreen(token, false);
12037 return translucentChanged;
12040 Binder.restoreCallingIdentity(origId);
12045 public boolean requestVisibleBehind(IBinder token, boolean visible) {
12046 final long origId = Binder.clearCallingIdentity();
12048 synchronized (this) {
12049 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12051 return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12056 Binder.restoreCallingIdentity(origId);
12061 public boolean isBackgroundVisibleBehind(IBinder token) {
12062 final long origId = Binder.clearCallingIdentity();
12064 synchronized (this) {
12065 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12066 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12067 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12068 "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12072 Binder.restoreCallingIdentity(origId);
12077 public ActivityOptions getActivityOptions(IBinder token) {
12078 final long origId = Binder.clearCallingIdentity();
12080 synchronized (this) {
12081 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12083 final ActivityOptions activityOptions = r.pendingOptions;
12084 r.pendingOptions = null;
12085 return activityOptions;
12090 Binder.restoreCallingIdentity(origId);
12095 public void setImmersive(IBinder token, boolean immersive) {
12096 synchronized(this) {
12097 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12099 throw new IllegalArgumentException();
12101 r.immersive = immersive;
12103 // update associated state if we're frontmost
12104 if (r == mFocusedActivity) {
12105 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12106 applyUpdateLockStateLocked(r);
12112 public boolean isImmersive(IBinder token) {
12113 synchronized (this) {
12114 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12116 throw new IllegalArgumentException();
12118 return r.immersive;
12123 public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12124 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12125 throw new UnsupportedOperationException("VR mode not supported on this device!");
12128 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12131 synchronized (this) {
12132 r = ActivityRecord.isInStackLocked(token);
12136 throw new IllegalArgumentException();
12140 if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12141 VrManagerInternal.NO_ERROR) {
12145 synchronized(this) {
12146 r.requestedVrComponent = (enabled) ? packageName : null;
12148 // Update associated state if this activity is currently focused
12149 if (r == mFocusedActivity) {
12150 applyUpdateVrModeLocked(r);
12157 public boolean isVrModePackageEnabled(ComponentName packageName) {
12158 if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12159 throw new UnsupportedOperationException("VR mode not supported on this device!");
12162 final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12164 return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12165 VrManagerInternal.NO_ERROR;
12168 public boolean isTopActivityImmersive() {
12169 enforceNotIsolatedCaller("startActivity");
12170 synchronized (this) {
12171 ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12172 return (r != null) ? r.immersive : false;
12177 public boolean isTopOfTask(IBinder token) {
12178 synchronized (this) {
12179 ActivityRecord r = ActivityRecord.isInStackLocked(token);
12181 throw new IllegalArgumentException();
12183 return r.task.getTopActivity() == r;
12187 public final void enterSafeMode() {
12188 synchronized(this) {
12189 // It only makes sense to do this before the system is ready
12190 // and started launching other packages.
12191 if (!mSystemReady) {
12193 AppGlobals.getPackageManager().enterSafeMode();
12194 } catch (RemoteException e) {
12202 public final void showSafeModeOverlay() {
12203 View v = LayoutInflater.from(mContext).inflate(
12204 com.android.internal.R.layout.safe_mode, null);
12205 WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12206 lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12207 lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12208 lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12209 lp.gravity = Gravity.BOTTOM | Gravity.START;
12210 lp.format = v.getBackground().getOpacity();
12211 lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12212 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12213 lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12214 ((WindowManager)mContext.getSystemService(
12215 Context.WINDOW_SERVICE)).addView(v, lp);
12218 public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12219 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12222 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12223 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12224 synchronized (stats) {
12225 if (mBatteryStatsService.isOnBattery()) {
12226 mBatteryStatsService.enforceCallingPermission();
12227 int MY_UID = Binder.getCallingUid();
12229 if (sender == null) {
12232 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12234 BatteryStatsImpl.Uid.Pkg pkg =
12235 stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12236 sourcePkg != null ? sourcePkg : rec.key.packageName);
12237 pkg.noteWakeupAlarmLocked(tag);
12242 public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12243 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12246 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12247 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12248 synchronized (stats) {
12249 mBatteryStatsService.enforceCallingPermission();
12250 int MY_UID = Binder.getCallingUid();
12252 if (sender == null) {
12255 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12257 mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12261 public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12262 if (sender != null && !(sender instanceof PendingIntentRecord)) {
12265 final PendingIntentRecord rec = (PendingIntentRecord)sender;
12266 final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12267 synchronized (stats) {
12268 mBatteryStatsService.enforceCallingPermission();
12269 int MY_UID = Binder.getCallingUid();
12271 if (sender == null) {
12274 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12276 mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12280 public boolean killPids(int[] pids, String pReason, boolean secure) {
12281 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12282 throw new SecurityException("killPids only available to the system");
12284 String reason = (pReason == null) ? "Unknown" : pReason;
12285 // XXX Note: don't acquire main activity lock here, because the window
12286 // manager calls in with its locks held.
12288 boolean killed = false;
12289 synchronized (mPidsSelfLocked) {
12291 for (int i=0; i<pids.length; i++) {
12292 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12293 if (proc != null) {
12294 int type = proc.setAdj;
12295 if (type > worstType) {
12301 // If the worst oom_adj is somewhere in the cached proc LRU range,
12302 // then constrain it so we will kill all cached procs.
12303 if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12304 && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12305 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12308 // If this is not a secure call, don't let it kill processes that
12310 if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12311 worstType = ProcessList.SERVICE_ADJ;
12314 Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12315 for (int i=0; i<pids.length; i++) {
12316 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12317 if (proc == null) {
12320 int adj = proc.setAdj;
12321 if (adj >= worstType && !proc.killedByAm) {
12322 proc.kill(reason, true);
12331 public void killUid(int appId, int userId, String reason) {
12332 enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12333 synchronized (this) {
12334 final long identity = Binder.clearCallingIdentity();
12336 killPackageProcessesLocked(null, appId, userId,
12337 ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12338 reason != null ? reason : "kill uid");
12340 Binder.restoreCallingIdentity(identity);
12346 public boolean killProcessesBelowForeground(String reason) {
12347 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12348 throw new SecurityException("killProcessesBelowForeground() only available to system");
12351 return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12354 private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12355 if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12356 throw new SecurityException("killProcessesBelowAdj() only available to system");
12359 boolean killed = false;
12360 synchronized (mPidsSelfLocked) {
12361 final int size = mPidsSelfLocked.size();
12362 for (int i = 0; i < size; i++) {
12363 final int pid = mPidsSelfLocked.keyAt(i);
12364 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12365 if (proc == null) continue;
12367 final int adj = proc.setAdj;
12368 if (adj > belowAdj && !proc.killedByAm) {
12369 proc.kill(reason, true);
12378 public void hang(final IBinder who, boolean allowRestart) {
12379 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12380 != PackageManager.PERMISSION_GRANTED) {
12381 throw new SecurityException("Requires permission "
12382 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12385 final IBinder.DeathRecipient death = new DeathRecipient() {
12387 public void binderDied() {
12388 synchronized (this) {
12395 who.linkToDeath(death, 0);
12396 } catch (RemoteException e) {
12397 Slog.w(TAG, "hang: given caller IBinder is already dead.");
12401 synchronized (this) {
12402 Watchdog.getInstance().setAllowRestart(allowRestart);
12403 Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12404 synchronized (death) {
12405 while (who.isBinderAlive()) {
12408 } catch (InterruptedException e) {
12412 Watchdog.getInstance().setAllowRestart(true);
12417 public void restart() {
12418 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12419 != PackageManager.PERMISSION_GRANTED) {
12420 throw new SecurityException("Requires permission "
12421 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12424 Log.i(TAG, "Sending shutdown broadcast...");
12426 BroadcastReceiver br = new BroadcastReceiver() {
12427 @Override public void onReceive(Context context, Intent intent) {
12428 // Now the broadcast is done, finish up the low-level shutdown.
12429 Log.i(TAG, "Shutting down activity manager...");
12431 Log.i(TAG, "Shutdown complete, restarting!");
12432 Process.killProcess(Process.myPid());
12437 // First send the high-level shut down broadcast.
12438 Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
12439 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
12440 intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
12441 /* For now we are not doing a clean shutdown, because things seem to get unhappy.
12442 mContext.sendOrderedBroadcastAsUser(intent,
12443 UserHandle.ALL, null, br, mHandler, 0, null, null);
12445 br.onReceive(mContext, intent);
12448 private long getLowRamTimeSinceIdle(long now) {
12449 return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
12453 public void performIdleMaintenance() {
12454 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12455 != PackageManager.PERMISSION_GRANTED) {
12456 throw new SecurityException("Requires permission "
12457 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12460 synchronized (this) {
12461 final long now = SystemClock.uptimeMillis();
12462 final long timeSinceLastIdle = now - mLastIdleTime;
12463 final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
12464 mLastIdleTime = now;
12465 mLowRamTimeSinceLastIdle = 0;
12466 if (mLowRamStartTime != 0) {
12467 mLowRamStartTime = now;
12470 StringBuilder sb = new StringBuilder(128);
12471 sb.append("Idle maintenance over ");
12472 TimeUtils.formatDuration(timeSinceLastIdle, sb);
12473 sb.append(" low RAM for ");
12474 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12475 Slog.i(TAG, sb.toString());
12477 // If at least 1/3 of our time since the last idle period has been spent
12478 // with RAM low, then we want to kill processes.
12479 boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
12481 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
12482 ProcessRecord proc = mLruProcesses.get(i);
12483 if (proc.notCachedSinceIdle) {
12484 if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
12485 && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
12486 && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
12487 if (doKilling && proc.initialIdlePss != 0
12488 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
12489 sb = new StringBuilder(128);
12491 sb.append(proc.processName);
12492 sb.append(" in idle maint: pss=");
12493 sb.append(proc.lastPss);
12494 sb.append(", swapPss=");
12495 sb.append(proc.lastSwapPss);
12496 sb.append(", initialPss=");
12497 sb.append(proc.initialIdlePss);
12498 sb.append(", period=");
12499 TimeUtils.formatDuration(timeSinceLastIdle, sb);
12500 sb.append(", lowRamPeriod=");
12501 TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
12502 Slog.wtfQuiet(TAG, sb.toString());
12503 proc.kill("idle maint (pss " + proc.lastPss
12504 + " from " + proc.initialIdlePss + ")", true);
12507 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
12508 && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
12509 proc.notCachedSinceIdle = true;
12510 proc.initialIdlePss = 0;
12511 proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
12512 mTestPssMode, isSleeping(), now);
12516 mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
12517 mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
12521 private void retrieveSettings() {
12522 final ContentResolver resolver = mContext.getContentResolver();
12523 final boolean freeformWindowManagement =
12524 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
12525 || Settings.Global.getInt(
12526 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
12527 final boolean supportsPictureInPicture =
12528 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
12530 final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
12531 final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
12532 final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
12533 final boolean alwaysFinishActivities =
12534 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
12535 final boolean lenientBackgroundCheck =
12536 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
12537 final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
12538 final boolean forceResizable = Settings.Global.getInt(
12539 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
12540 // Transfer any global setting for forcing RTL layout, into a System Property
12541 SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
12543 final Configuration configuration = new Configuration();
12544 Settings.System.getConfiguration(resolver, configuration);
12546 // This will take care of setting the correct layout direction flags
12547 configuration.setLayoutDirection(configuration.locale);
12550 synchronized (this) {
12551 mDebugApp = mOrigDebugApp = debugApp;
12552 mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
12553 mAlwaysFinishActivities = alwaysFinishActivities;
12554 mLenientBackgroundCheck = lenientBackgroundCheck;
12555 mForceResizableActivities = forceResizable;
12556 mWindowManager.setForceResizableTasks(mForceResizableActivities);
12557 if (supportsMultiWindow || forceResizable) {
12558 mSupportsMultiWindow = true;
12559 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
12560 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
12562 mSupportsMultiWindow = false;
12563 mSupportsFreeformWindowManagement = false;
12564 mSupportsPictureInPicture = false;
12566 // This happens before any activities are started, so we can
12567 // change mConfiguration in-place.
12568 updateConfigurationLocked(configuration, null, true);
12569 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
12570 "Initial config: " + mConfiguration);
12572 // Load resources only after the current configuration has been set.
12573 final Resources res = mContext.getResources();
12574 mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
12575 mThumbnailWidth = res.getDimensionPixelSize(
12576 com.android.internal.R.dimen.thumbnail_width);
12577 mThumbnailHeight = res.getDimensionPixelSize(
12578 com.android.internal.R.dimen.thumbnail_height);
12579 mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
12580 com.android.internal.R.string.config_defaultPictureInPictureBounds));
12581 mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
12582 com.android.internal.R.string.config_appsNotReportingCrashes));
12586 public boolean testIsSystemReady() {
12587 // no need to synchronize(this) just to read & return the value
12588 return mSystemReady;
12591 private static File getCalledPreBootReceiversFile() {
12592 File dataDir = Environment.getDataDirectory();
12593 File systemDir = new File(dataDir, "system");
12594 File fname = new File(systemDir, CALLED_PRE_BOOTS_FILENAME);
12598 private static ArrayList<ComponentName> readLastDonePreBootReceivers() {
12599 ArrayList<ComponentName> lastDoneReceivers = new ArrayList<ComponentName>();
12600 File file = getCalledPreBootReceiversFile();
12601 FileInputStream fis = null;
12603 fis = new FileInputStream(file);
12604 DataInputStream dis = new DataInputStream(new BufferedInputStream(fis, 2048));
12605 int fvers = dis.readInt();
12606 if (fvers == LAST_PREBOOT_DELIVERED_FILE_VERSION) {
12607 String vers = dis.readUTF();
12608 String codename = dis.readUTF();
12609 String build = dis.readUTF();
12610 if (android.os.Build.VERSION.RELEASE.equals(vers)
12611 && android.os.Build.VERSION.CODENAME.equals(codename)
12612 && android.os.Build.VERSION.INCREMENTAL.equals(build)) {
12613 int num = dis.readInt();
12616 String pkg = dis.readUTF();
12617 String cls = dis.readUTF();
12618 lastDoneReceivers.add(new ComponentName(pkg, cls));
12622 } catch (FileNotFoundException e) {
12623 } catch (IOException e) {
12624 Slog.w(TAG, "Failure reading last done pre-boot receivers", e);
12629 } catch (IOException e) {
12633 return lastDoneReceivers;
12636 private static void writeLastDonePreBootReceivers(ArrayList<ComponentName> list) {
12637 File file = getCalledPreBootReceiversFile();
12638 FileOutputStream fos = null;
12639 DataOutputStream dos = null;
12641 fos = new FileOutputStream(file);
12642 dos = new DataOutputStream(new BufferedOutputStream(fos, 2048));
12643 dos.writeInt(LAST_PREBOOT_DELIVERED_FILE_VERSION);
12644 dos.writeUTF(android.os.Build.VERSION.RELEASE);
12645 dos.writeUTF(android.os.Build.VERSION.CODENAME);
12646 dos.writeUTF(android.os.Build.VERSION.INCREMENTAL);
12647 dos.writeInt(list.size());
12648 for (int i=0; i<list.size(); i++) {
12649 dos.writeUTF(list.get(i).getPackageName());
12650 dos.writeUTF(list.get(i).getClassName());
12652 } catch (IOException e) {
12653 Slog.w(TAG, "Failure writing last done pre-boot receivers", e);
12656 FileUtils.sync(fos);
12660 } catch (IOException e) {
12661 // TODO Auto-generated catch block
12662 e.printStackTrace();
12668 final class PreBootContinuation extends IIntentReceiver.Stub {
12669 final Intent intent;
12670 final Runnable onFinishCallback;
12671 final ArrayList<ComponentName> doneReceivers;
12672 final List<ResolveInfo> ris;
12678 PreBootContinuation(Intent _intent, Runnable _onFinishCallback,
12679 ArrayList<ComponentName> _doneReceivers, List<ResolveInfo> _ris, int[] _users) {
12681 onFinishCallback = _onFinishCallback;
12682 doneReceivers = _doneReceivers;
12688 if (lastRi != curRi) {
12689 ActivityInfo ai = ris.get(curRi).activityInfo;
12690 ComponentName comp = new ComponentName(ai.packageName, ai.name);
12691 intent.setComponent(comp);
12692 doneReceivers.add(comp);
12694 CharSequence label = ai.loadLabel(mContext.getPackageManager());
12695 showBootMessage(mContext.getString(R.string.android_preparing_apk, label), false);
12697 Slog.i(TAG, "Pre-boot of " + intent.getComponent().toShortString()
12698 + " for user " + users[curUser]);
12699 EventLogTags.writeAmPreBoot(users[curUser], intent.getComponent().getPackageName());
12700 broadcastIntentLocked(null, null, intent, null, this,
12701 0, null, null, null, AppOpsManager.OP_NONE,
12702 null, true, false, MY_PID, Process.SYSTEM_UID, users[curUser]);
12705 public void performReceive(Intent intent, int resultCode,
12706 String data, Bundle extras, boolean ordered,
12707 boolean sticky, int sendingUser) {
12709 if (curUser >= users.length) {
12712 if (curRi >= ris.size()) {
12713 // All done sending broadcasts!
12714 if (onFinishCallback != null) {
12715 // The raw IIntentReceiver interface is called
12716 // with the AM lock held, so redispatch to
12717 // execute our code without the lock.
12718 mHandler.post(onFinishCallback);
12727 private boolean deliverPreBootCompleted(final Runnable onFinishCallback,
12728 ArrayList<ComponentName> doneReceivers) {
12729 Intent intent = new Intent(Intent.ACTION_PRE_BOOT_COMPLETED);
12730 List<ResolveInfo> ris = null;
12732 ris = AppGlobals.getPackageManager().queryIntentReceivers(
12733 intent, null, MATCH_SYSTEM_ONLY, UserHandle.USER_SYSTEM).getList();
12734 } catch (RemoteException e) {
12739 intent.addFlags(Intent.FLAG_RECEIVER_BOOT_UPGRADE | Intent.FLAG_DEBUG_TRIAGED_MISSING);
12741 ArrayList<ComponentName> lastDoneReceivers = readLastDonePreBootReceivers();
12742 for (int i=0; i<ris.size(); i++) {
12743 ActivityInfo ai = ris.get(i).activityInfo;
12744 ComponentName comp = new ComponentName(ai.packageName, ai.name);
12745 if (lastDoneReceivers.contains(comp)) {
12746 // We already did the pre boot receiver for this app with the current
12747 // platform version, so don't do it again...
12750 // ...however, do keep it as one that has been done, so we don't
12751 // forget about it when rewriting the file of last done receivers.
12752 doneReceivers.add(comp);
12756 if (ris.size() <= 0) {
12760 // TODO: can we still do this with per user encryption?
12761 final int[] users = mUserController.getUsers();
12762 if (users.length <= 0) {
12766 PreBootContinuation cont = new PreBootContinuation(intent, onFinishCallback, doneReceivers,
12772 public void systemReady(final Runnable goingCallback) {
12773 synchronized(this) {
12774 if (mSystemReady) {
12775 // If we're done calling all the receivers, run the next "boot phase" passed in
12776 // by the SystemServer
12777 if (goingCallback != null) {
12778 goingCallback.run();
12783 mLocalDeviceIdleController
12784 = LocalServices.getService(DeviceIdleController.LocalService.class);
12786 // Make sure we have the current profile info, since it is needed for security checks.
12787 mUserController.onSystemReady();
12789 mRecentTasks.onSystemReadyLocked();
12790 // Check to see if there are any update receivers to run.
12792 if (mWaitingUpdate) {
12795 final ArrayList<ComponentName> doneReceivers = new ArrayList<ComponentName>();
12796 mWaitingUpdate = deliverPreBootCompleted(new Runnable() {
12797 public void run() {
12798 synchronized (ActivityManagerService.this) {
12801 showBootMessage(mContext.getText(
12802 R.string.android_upgrading_complete),
12804 writeLastDonePreBootReceivers(doneReceivers);
12805 systemReady(goingCallback);
12809 if (mWaitingUpdate) {
12815 mAppOpsService.systemReady();
12816 mSystemReady = true;
12819 ArrayList<ProcessRecord> procsToKill = null;
12820 synchronized(mPidsSelfLocked) {
12821 for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
12822 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12823 if (!isAllowedWhileBooting(proc.info)){
12824 if (procsToKill == null) {
12825 procsToKill = new ArrayList<ProcessRecord>();
12827 procsToKill.add(proc);
12832 synchronized(this) {
12833 if (procsToKill != null) {
12834 for (int i=procsToKill.size()-1; i>=0; i--) {
12835 ProcessRecord proc = procsToKill.get(i);
12836 Slog.i(TAG, "Removing system update proc: " + proc);
12837 removeProcessLocked(proc, true, false, "system update done");
12841 // Now that we have cleaned up any update processes, we
12842 // are ready to start launching real processes and know that
12843 // we won't trample on them any more.
12844 mProcessesReady = true;
12847 Slog.i(TAG, "System now ready");
12848 EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
12849 SystemClock.uptimeMillis());
12851 synchronized(this) {
12852 // Make sure we have no pre-ready processes sitting around.
12854 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
12855 ResolveInfo ri = mContext.getPackageManager()
12856 .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
12858 CharSequence errorMsg = null;
12860 ActivityInfo ai = ri.activityInfo;
12861 ApplicationInfo app = ai.applicationInfo;
12862 if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
12863 mTopAction = Intent.ACTION_FACTORY_TEST;
12865 mTopComponent = new ComponentName(app.packageName,
12868 errorMsg = mContext.getResources().getText(
12869 com.android.internal.R.string.factorytest_not_system);
12872 errorMsg = mContext.getResources().getText(
12873 com.android.internal.R.string.factorytest_no_action);
12875 if (errorMsg != null) {
12878 mTopComponent = null;
12879 Message msg = Message.obtain();
12880 msg.what = SHOW_FACTORY_ERROR_UI_MSG;
12881 msg.getData().putCharSequence("msg", errorMsg);
12882 mUiHandler.sendMessage(msg);
12887 retrieveSettings();
12888 final int currentUserId;
12889 synchronized (this) {
12890 currentUserId = mUserController.getCurrentUserIdLocked();
12891 readGrantedUriPermissionsLocked();
12894 if (goingCallback != null) goingCallback.run();
12896 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
12897 Integer.toString(currentUserId), currentUserId);
12898 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
12899 Integer.toString(currentUserId), currentUserId);
12900 mSystemServiceManager.startUser(currentUserId);
12902 synchronized (this) {
12903 // Only start up encryption-aware persistent apps; once user is
12904 // unlocked we'll come back around and start unaware apps
12905 startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
12907 // Start up initial activity.
12909 // Enable home activity for system user, so that the system can always boot
12910 if (UserManager.isSplitSystemUser()) {
12911 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
12913 AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
12914 PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
12915 UserHandle.USER_SYSTEM);
12916 } catch (RemoteException e) {
12917 throw e.rethrowAsRuntimeException();
12920 startHomeActivityLocked(currentUserId, "systemReady");
12923 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
12924 Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
12925 + " data partition or your device will be unstable.");
12926 mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
12928 } catch (RemoteException e) {
12931 if (!Build.isBuildConsistent()) {
12932 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
12933 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
12936 long ident = Binder.clearCallingIdentity();
12938 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
12939 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
12940 | Intent.FLAG_RECEIVER_FOREGROUND);
12941 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12942 broadcastIntentLocked(null, null, intent,
12943 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
12944 null, false, false, MY_PID, Process.SYSTEM_UID,
12946 intent = new Intent(Intent.ACTION_USER_STARTING);
12947 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
12948 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
12949 broadcastIntentLocked(null, null, intent,
12950 null, new IIntentReceiver.Stub() {
12952 public void performReceive(Intent intent, int resultCode, String data,
12953 Bundle extras, boolean ordered, boolean sticky, int sendingUser)
12954 throws RemoteException {
12957 new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
12958 null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
12959 } catch (Throwable t) {
12960 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
12962 Binder.restoreCallingIdentity(ident);
12964 mStackSupervisor.resumeFocusedStackTopActivityLocked();
12965 mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
12969 void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
12970 synchronized (this) {
12971 mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
12975 void skipCurrentReceiverLocked(ProcessRecord app) {
12976 for (BroadcastQueue queue : mBroadcastQueues) {
12977 queue.skipCurrentReceiverLocked(app);
12982 * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
12983 * The application process will exit immediately after this call returns.
12984 * @param app object of the crashing app, null for the system server
12985 * @param crashInfo describing the exception
12987 public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
12988 ProcessRecord r = findAppProcess(app, "Crash");
12989 final String processName = app == null ? "system_server"
12990 : (r == null ? "unknown" : r.processName);
12992 handleApplicationCrashInner("crash", r, processName, crashInfo);
12995 /* Native crash reporting uses this inner version because it needs to be somewhat
12996 * decoupled from the AM-managed cleanup lifecycle
12998 void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
12999 ApplicationErrorReport.CrashInfo crashInfo) {
13000 EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13001 UserHandle.getUserId(Binder.getCallingUid()), processName,
13002 r == null ? -1 : r.info.flags,
13003 crashInfo.exceptionClassName,
13004 crashInfo.exceptionMessage,
13005 crashInfo.throwFileName,
13006 crashInfo.throwLineNumber);
13008 addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13010 mAppErrors.crashApplication(r, crashInfo);
13013 public void handleApplicationStrictModeViolation(
13016 StrictMode.ViolationInfo info) {
13017 ProcessRecord r = findAppProcess(app, "StrictMode");
13022 if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13023 Integer stackFingerprint = info.hashCode();
13024 boolean logIt = true;
13025 synchronized (mAlreadyLoggedViolatedStacks) {
13026 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13028 // TODO: sub-sample into EventLog for these, with
13029 // the info.durationMillis? Then we'd get
13030 // the relative pain numbers, without logging all
13031 // the stack traces repeatedly. We'd want to do
13032 // likewise in the client code, which also does
13033 // dup suppression, before the Binder call.
13035 if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13036 mAlreadyLoggedViolatedStacks.clear();
13038 mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13042 logStrictModeViolationToDropBox(r, info);
13046 if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13047 AppErrorResult result = new AppErrorResult();
13048 synchronized (this) {
13049 final long origId = Binder.clearCallingIdentity();
13051 Message msg = Message.obtain();
13052 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13053 HashMap<String, Object> data = new HashMap<String, Object>();
13054 data.put("result", result);
13055 data.put("app", r);
13056 data.put("violationMask", violationMask);
13057 data.put("info", info);
13059 mUiHandler.sendMessage(msg);
13061 Binder.restoreCallingIdentity(origId);
13063 int res = result.get();
13064 Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13068 // Depending on the policy in effect, there could be a bunch of
13069 // these in quick succession so we try to batch these together to
13070 // minimize disk writes, number of dropbox entries, and maximize
13071 // compression, by having more fewer, larger records.
13072 private void logStrictModeViolationToDropBox(
13073 ProcessRecord process,
13074 StrictMode.ViolationInfo info) {
13075 if (info == null) {
13078 final boolean isSystemApp = process == null ||
13079 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13080 ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13081 final String processName = process == null ? "unknown" : process.processName;
13082 final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13083 final DropBoxManager dbox = (DropBoxManager)
13084 mContext.getSystemService(Context.DROPBOX_SERVICE);
13086 // Exit early if the dropbox isn't configured to accept this report type.
13087 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13089 boolean bufferWasEmpty;
13090 boolean needsFlush;
13091 final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13092 synchronized (sb) {
13093 bufferWasEmpty = sb.length() == 0;
13094 appendDropBoxProcessHeaders(process, processName, sb);
13095 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13096 sb.append("System-App: ").append(isSystemApp).append("\n");
13097 sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13098 if (info.violationNumThisLoop != 0) {
13099 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13101 if (info.numAnimationsRunning != 0) {
13102 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13104 if (info.broadcastIntentAction != null) {
13105 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13107 if (info.durationMillis != -1) {
13108 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13110 if (info.numInstances != -1) {
13111 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13113 if (info.tags != null) {
13114 for (String tag : info.tags) {
13115 sb.append("Span-Tag: ").append(tag).append("\n");
13119 if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13120 sb.append(info.crashInfo.stackTrace);
13123 if (info.message != null) {
13124 sb.append(info.message);
13128 // Only buffer up to ~64k. Various logging bits truncate
13130 needsFlush = (sb.length() > 64 * 1024);
13133 // Flush immediately if the buffer's grown too large, or this
13134 // is a non-system app. Non-system apps are isolated with a
13135 // different tag & policy and not batched.
13137 // Batching is useful during internal testing with
13138 // StrictMode settings turned up high. Without batching,
13139 // thousands of separate files could be created on boot.
13140 if (!isSystemApp || needsFlush) {
13141 new Thread("Error dump: " + dropboxTag) {
13143 public void run() {
13145 synchronized (sb) {
13146 report = sb.toString();
13147 sb.delete(0, sb.length());
13150 if (report.length() != 0) {
13151 dbox.addText(dropboxTag, report);
13158 // System app batching:
13159 if (!bufferWasEmpty) {
13160 // An existing dropbox-writing thread is outstanding, so
13161 // we don't need to start it up. The existing thread will
13162 // catch the buffer appends we just did.
13166 // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13167 // (After this point, we shouldn't access AMS internal data structures.)
13168 new Thread("Error dump: " + dropboxTag) {
13170 public void run() {
13171 // 5 second sleep to let stacks arrive and be batched together
13173 Thread.sleep(5000); // 5 seconds
13174 } catch (InterruptedException e) {}
13176 String errorReport;
13177 synchronized (mStrictModeBuffer) {
13178 errorReport = mStrictModeBuffer.toString();
13179 if (errorReport.length() == 0) {
13182 mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13183 mStrictModeBuffer.trimToSize();
13185 dbox.addText(dropboxTag, errorReport);
13191 * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13192 * @param app object of the crashing app, null for the system server
13193 * @param tag reported by the caller
13194 * @param system whether this wtf is coming from the system
13195 * @param crashInfo describing the context of the error
13196 * @return true if the process should exit immediately (WTF is fatal)
13198 public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13199 final ApplicationErrorReport.CrashInfo crashInfo) {
13200 final int callingUid = Binder.getCallingUid();
13201 final int callingPid = Binder.getCallingPid();
13204 // If this is coming from the system, we could very well have low-level
13205 // system locks held, so we want to do this all asynchronously. And we
13206 // never want this to become fatal, so there is that too.
13207 mHandler.post(new Runnable() {
13208 @Override public void run() {
13209 handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13215 final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13218 if (r != null && r.pid != Process.myPid() &&
13219 Settings.Global.getInt(mContext.getContentResolver(),
13220 Settings.Global.WTF_IS_FATAL, 0) != 0) {
13221 mAppErrors.crashApplication(r, crashInfo);
13228 ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13229 final ApplicationErrorReport.CrashInfo crashInfo) {
13230 final ProcessRecord r = findAppProcess(app, "WTF");
13231 final String processName = app == null ? "system_server"
13232 : (r == null ? "unknown" : r.processName);
13234 EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13235 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13237 addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13243 * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13244 * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13246 private ProcessRecord findAppProcess(IBinder app, String reason) {
13251 synchronized (this) {
13252 final int NP = mProcessNames.getMap().size();
13253 for (int ip=0; ip<NP; ip++) {
13254 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13255 final int NA = apps.size();
13256 for (int ia=0; ia<NA; ia++) {
13257 ProcessRecord p = apps.valueAt(ia);
13258 if (p.thread != null && p.thread.asBinder() == app) {
13264 Slog.w(TAG, "Can't find mystery application for " + reason
13265 + " from pid=" + Binder.getCallingPid()
13266 + " uid=" + Binder.getCallingUid() + ": " + app);
13272 * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13273 * to append various headers to the dropbox log text.
13275 private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13276 StringBuilder sb) {
13277 // Watchdog thread ends up invoking this function (with
13278 // a null ProcessRecord) to add the stack file to dropbox.
13279 // Do not acquire a lock on this (am) in such cases, as it
13280 // could cause a potential deadlock, if and when watchdog
13281 // is invoked due to unavailability of lock on am and it
13282 // would prevent watchdog from killing system_server.
13283 if (process == null) {
13284 sb.append("Process: ").append(processName).append("\n");
13287 // Note: ProcessRecord 'process' is guarded by the service
13288 // instance. (notably process.pkgList, which could otherwise change
13289 // concurrently during execution of this method)
13290 synchronized (this) {
13291 sb.append("Process: ").append(processName).append("\n");
13292 int flags = process.info.flags;
13293 IPackageManager pm = AppGlobals.getPackageManager();
13294 sb.append("Flags: 0x").append(Integer.toString(flags, 16)).append("\n");
13295 for (int ip=0; ip<process.pkgList.size(); ip++) {
13296 String pkg = process.pkgList.keyAt(ip);
13297 sb.append("Package: ").append(pkg);
13299 PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13301 sb.append(" v").append(pi.versionCode);
13302 if (pi.versionName != null) {
13303 sb.append(" (").append(pi.versionName).append(")");
13306 } catch (RemoteException e) {
13307 Slog.e(TAG, "Error getting package info: " + pkg, e);
13314 private static String processClass(ProcessRecord process) {
13315 if (process == null || process.pid == MY_PID) {
13316 return "system_server";
13317 } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13318 return "system_app";
13325 * Write a description of an error (crash, WTF, ANR) to the drop box.
13326 * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13327 * @param process which caused the error, null means the system server
13328 * @param activity which triggered the error, null if unknown
13329 * @param parent activity related to the error, null if unknown
13330 * @param subject line related to the error, null if absent
13331 * @param report in long form describing the error, null if absent
13332 * @param logFile to include in the report, null if none
13333 * @param crashInfo giving an application stack trace, null if absent
13335 public void addErrorToDropBox(String eventType,
13336 ProcessRecord process, String processName, ActivityRecord activity,
13337 ActivityRecord parent, String subject,
13338 final String report, final File logFile,
13339 final ApplicationErrorReport.CrashInfo crashInfo) {
13340 // NOTE -- this must never acquire the ActivityManagerService lock,
13341 // otherwise the watchdog may be prevented from resetting the system.
13343 final String dropboxTag = processClass(process) + "_" + eventType;
13344 final DropBoxManager dbox = (DropBoxManager)
13345 mContext.getSystemService(Context.DROPBOX_SERVICE);
13347 // Exit early if the dropbox isn't configured to accept this report type.
13348 if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13350 final StringBuilder sb = new StringBuilder(1024);
13351 appendDropBoxProcessHeaders(process, processName, sb);
13352 if (process != null) {
13353 sb.append("Foreground: ")
13354 .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13357 if (activity != null) {
13358 sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13360 if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13361 sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13363 if (parent != null && parent != activity) {
13364 sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13366 if (subject != null) {
13367 sb.append("Subject: ").append(subject).append("\n");
13369 sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13370 if (Debug.isDebuggerConnected()) {
13371 sb.append("Debugger: Connected\n");
13375 // Do the rest in a worker thread to avoid blocking the caller on I/O
13376 // (After this point, we shouldn't access AMS internal data structures.)
13377 Thread worker = new Thread("Error dump: " + dropboxTag) {
13379 public void run() {
13380 if (report != null) {
13383 if (logFile != null) {
13385 sb.append(FileUtils.readTextFile(logFile, DROPBOX_MAX_SIZE,
13386 "\n\n[[TRUNCATED]]"));
13387 } catch (IOException e) {
13388 Slog.e(TAG, "Error reading " + logFile, e);
13391 if (crashInfo != null && crashInfo.stackTrace != null) {
13392 sb.append(crashInfo.stackTrace);
13395 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13396 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13400 // Merge several logcat streams, and take the last N lines
13401 InputStreamReader input = null;
13403 java.lang.Process logcat = new ProcessBuilder("/system/bin/logcat",
13404 "-v", "time", "-b", "events", "-b", "system", "-b", "main",
13406 "-t", String.valueOf(lines)).redirectErrorStream(true).start();
13408 try { logcat.getOutputStream().close(); } catch (IOException e) {}
13409 try { logcat.getErrorStream().close(); } catch (IOException e) {}
13410 input = new InputStreamReader(logcat.getInputStream());
13413 char[] buf = new char[8192];
13414 while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13415 } catch (IOException e) {
13416 Slog.e(TAG, "Error running logcat", e);
13418 if (input != null) try { input.close(); } catch (IOException e) {}
13422 dbox.addText(dropboxTag, sb.toString());
13426 if (process == null) {
13427 // If process is null, we are being called from some internal code
13428 // and may be about to die -- run this synchronously.
13435 public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13436 enforceNotIsolatedCaller("getProcessesInErrorState");
13437 // assume our apps are happy - lazy create the list
13438 List<ActivityManager.ProcessErrorStateInfo> errList = null;
13440 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13441 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13442 int userId = UserHandle.getUserId(Binder.getCallingUid());
13444 synchronized (this) {
13446 // iterate across all processes
13447 for (int i=mLruProcesses.size()-1; i>=0; i--) {
13448 ProcessRecord app = mLruProcesses.get(i);
13449 if (!allUsers && app.userId != userId) {
13452 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13453 // This one's in trouble, so we'll generate a report for it
13454 // crashes are higher priority (in case there's a crash *and* an anr)
13455 ActivityManager.ProcessErrorStateInfo report = null;
13456 if (app.crashing) {
13457 report = app.crashingReport;
13458 } else if (app.notResponding) {
13459 report = app.notRespondingReport;
13462 if (report != null) {
13463 if (errList == null) {
13464 errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13466 errList.add(report);
13468 Slog.w(TAG, "Missing app error report, app = " + app.processName +
13469 " crashing = " + app.crashing +
13470 " notResponding = " + app.notResponding);
13479 static int procStateToImportance(int procState, int memAdj,
13480 ActivityManager.RunningAppProcessInfo currApp) {
13481 int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13482 if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13483 currApp.lru = memAdj;
13490 private void fillInProcMemInfo(ProcessRecord app,
13491 ActivityManager.RunningAppProcessInfo outInfo) {
13492 outInfo.pid = app.pid;
13493 outInfo.uid = app.info.uid;
13494 if (mHeavyWeightProcess == app) {
13495 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13497 if (app.persistent) {
13498 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13500 if (app.activities.size() > 0) {
13501 outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13503 outInfo.lastTrimLevel = app.trimMemoryLevel;
13504 int adj = app.curAdj;
13505 int procState = app.curProcState;
13506 outInfo.importance = procStateToImportance(procState, adj, outInfo);
13507 outInfo.importanceReasonCode = app.adjTypeCode;
13508 outInfo.processState = app.curProcState;
13511 public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13512 enforceNotIsolatedCaller("getRunningAppProcesses");
13514 final int callingUid = Binder.getCallingUid();
13516 // Lazy instantiation of list
13517 List<ActivityManager.RunningAppProcessInfo> runList = null;
13518 final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13519 callingUid) == PackageManager.PERMISSION_GRANTED;
13520 final int userId = UserHandle.getUserId(callingUid);
13521 final boolean allUids = isGetTasksAllowed(
13522 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13524 synchronized (this) {
13525 // Iterate across all processes
13526 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13527 ProcessRecord app = mLruProcesses.get(i);
13528 if ((!allUsers && app.userId != userId)
13529 || (!allUids && app.uid != callingUid)) {
13532 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13533 // Generate process state info for running application
13534 ActivityManager.RunningAppProcessInfo currApp =
13535 new ActivityManager.RunningAppProcessInfo(app.processName,
13536 app.pid, app.getPackageList());
13537 fillInProcMemInfo(app, currApp);
13538 if (app.adjSource instanceof ProcessRecord) {
13539 currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13540 currApp.importanceReasonImportance =
13541 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13542 app.adjSourceProcState);
13543 } else if (app.adjSource instanceof ActivityRecord) {
13544 ActivityRecord r = (ActivityRecord)app.adjSource;
13545 if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13547 if (app.adjTarget instanceof ComponentName) {
13548 currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13550 //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13551 // + " lru=" + currApp.lru);
13552 if (runList == null) {
13553 runList = new ArrayList<>();
13555 runList.add(currApp);
13562 public List<ApplicationInfo> getRunningExternalApplications() {
13563 enforceNotIsolatedCaller("getRunningExternalApplications");
13564 List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13565 List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13566 if (runningApps != null && runningApps.size() > 0) {
13567 Set<String> extList = new HashSet<String>();
13568 for (ActivityManager.RunningAppProcessInfo app : runningApps) {
13569 if (app.pkgList != null) {
13570 for (String pkg : app.pkgList) {
13575 IPackageManager pm = AppGlobals.getPackageManager();
13576 for (String pkg : extList) {
13578 ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
13579 if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
13582 } catch (RemoteException e) {
13590 public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
13591 enforceNotIsolatedCaller("getMyMemoryState");
13592 synchronized (this) {
13593 ProcessRecord proc;
13594 synchronized (mPidsSelfLocked) {
13595 proc = mPidsSelfLocked.get(Binder.getCallingPid());
13597 fillInProcMemInfo(proc, outInfo);
13602 public int getMemoryTrimLevel() {
13603 enforceNotIsolatedCaller("getMyMemoryState");
13604 synchronized (this) {
13605 return mLastMemoryLevel;
13610 public void onShellCommand(FileDescriptor in, FileDescriptor out,
13611 FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
13612 (new ActivityManagerShellCommand(this, false)).exec(
13613 this, in, out, err, args, resultReceiver);
13617 protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
13618 if (checkCallingPermission(android.Manifest.permission.DUMP)
13619 != PackageManager.PERMISSION_GRANTED) {
13620 pw.println("Permission Denial: can't dump ActivityManager from from pid="
13621 + Binder.getCallingPid()
13622 + ", uid=" + Binder.getCallingUid()
13623 + " without permission "
13624 + android.Manifest.permission.DUMP);
13628 boolean dumpAll = false;
13629 boolean dumpClient = false;
13630 String dumpPackage = null;
13633 while (opti < args.length) {
13634 String opt = args[opti];
13635 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
13639 if ("-a".equals(opt)) {
13641 } else if ("-c".equals(opt)) {
13643 } else if ("-p".equals(opt)) {
13644 if (opti < args.length) {
13645 dumpPackage = args[opti];
13648 pw.println("Error: -p option requires package argument");
13652 } else if ("-h".equals(opt)) {
13653 ActivityManagerShellCommand.dumpHelp(pw, true);
13656 pw.println("Unknown argument: " + opt + "; use -h for help");
13660 long origId = Binder.clearCallingIdentity();
13661 boolean more = false;
13662 // Is the caller requesting to dump a particular piece of data?
13663 if (opti < args.length) {
13664 String cmd = args[opti];
13666 if ("activities".equals(cmd) || "a".equals(cmd)) {
13667 synchronized (this) {
13668 dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13670 } else if ("recents".equals(cmd) || "r".equals(cmd)) {
13671 synchronized (this) {
13672 dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
13674 } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
13677 if (opti >= args.length) {
13679 newArgs = EMPTY_STRING_ARRAY;
13681 dumpPackage = args[opti];
13683 newArgs = new String[args.length - opti];
13684 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13685 args.length - opti);
13687 synchronized (this) {
13688 dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
13690 } else if ("intents".equals(cmd) || "i".equals(cmd)) {
13693 if (opti >= args.length) {
13695 newArgs = EMPTY_STRING_ARRAY;
13697 dumpPackage = args[opti];
13699 newArgs = new String[args.length - opti];
13700 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13701 args.length - opti);
13703 synchronized (this) {
13704 dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
13706 } else if ("processes".equals(cmd) || "p".equals(cmd)) {
13709 if (opti >= args.length) {
13711 newArgs = EMPTY_STRING_ARRAY;
13713 dumpPackage = args[opti];
13715 newArgs = new String[args.length - opti];
13716 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13717 args.length - opti);
13719 synchronized (this) {
13720 dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
13722 } else if ("oom".equals(cmd) || "o".equals(cmd)) {
13723 synchronized (this) {
13724 dumpOomLocked(fd, pw, args, opti, true);
13726 } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
13727 synchronized (this) {
13728 dumpPermissionsLocked(fd, pw, args, opti, true, null);
13730 } else if ("provider".equals(cmd)) {
13733 if (opti >= args.length) {
13735 newArgs = EMPTY_STRING_ARRAY;
13739 newArgs = new String[args.length - opti];
13740 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
13742 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
13743 pw.println("No providers match: " + name);
13744 pw.println("Use -h for help.");
13746 } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
13747 synchronized (this) {
13748 dumpProvidersLocked(fd, pw, args, opti, true, null);
13750 } else if ("service".equals(cmd)) {
13753 if (opti >= args.length) {
13755 newArgs = EMPTY_STRING_ARRAY;
13759 newArgs = new String[args.length - opti];
13760 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13761 args.length - opti);
13763 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
13764 pw.println("No services match: " + name);
13765 pw.println("Use -h for help.");
13767 } else if ("package".equals(cmd)) {
13769 if (opti >= args.length) {
13770 pw.println("package: no package name specified");
13771 pw.println("Use -h for help.");
13773 dumpPackage = args[opti];
13775 newArgs = new String[args.length - opti];
13776 if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
13777 args.length - opti);
13782 } else if ("associations".equals(cmd) || "as".equals(cmd)) {
13783 synchronized (this) {
13784 dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13786 } else if ("services".equals(cmd) || "s".equals(cmd)) {
13787 synchronized (this) {
13788 mServices.dumpServicesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
13790 } else if ("locks".equals(cmd)) {
13791 LockGuard.dump(fd, pw, args);
13793 // Dumping a single activity?
13794 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
13795 ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
13796 int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
13798 pw.println("Bad activity command, or no activities match: " + cmd);
13799 pw.println("Use -h for help.");
13804 Binder.restoreCallingIdentity(origId);
13809 // No piece of data specified, dump everything.
13810 synchronized (this) {
13811 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13814 pw.println("-------------------------------------------------------------------------------");
13816 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13819 pw.println("-------------------------------------------------------------------------------");
13821 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13824 pw.println("-------------------------------------------------------------------------------");
13826 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13829 pw.println("-------------------------------------------------------------------------------");
13831 mServices.dumpServicesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13834 pw.println("-------------------------------------------------------------------------------");
13836 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13839 pw.println("-------------------------------------------------------------------------------");
13841 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13842 if (mAssociations.size() > 0) {
13845 pw.println("-------------------------------------------------------------------------------");
13847 dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
13851 pw.println("-------------------------------------------------------------------------------");
13853 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
13855 Binder.restoreCallingIdentity(origId);
13858 void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13859 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13860 pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
13862 boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
13864 boolean needSep = printedAnything;
13866 boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
13867 dumpPackage, needSep, " mFocusedActivity: ");
13869 printedAnything = true;
13873 if (dumpPackage == null) {
13878 printedAnything = true;
13879 mStackSupervisor.dump(pw, " ");
13882 if (!printedAnything) {
13883 pw.println(" (nothing)");
13887 void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13888 int opti, boolean dumpAll, String dumpPackage) {
13889 pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
13891 boolean printedAnything = false;
13893 if (mRecentTasks != null && mRecentTasks.size() > 0) {
13894 boolean printedHeader = false;
13896 final int N = mRecentTasks.size();
13897 for (int i=0; i<N; i++) {
13898 TaskRecord tr = mRecentTasks.get(i);
13899 if (dumpPackage != null) {
13900 if (tr.realActivity == null ||
13901 !dumpPackage.equals(tr.realActivity)) {
13905 if (!printedHeader) {
13906 pw.println(" Recent tasks:");
13907 printedHeader = true;
13908 printedAnything = true;
13910 pw.print(" * Recent #"); pw.print(i); pw.print(": ");
13913 mRecentTasks.get(i).dump(pw, " ");
13918 if (!printedAnything) {
13919 pw.println(" (nothing)");
13923 void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
13924 int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
13925 pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
13928 if (dumpPackage != null) {
13929 IPackageManager pm = AppGlobals.getPackageManager();
13931 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
13932 } catch (RemoteException e) {
13936 boolean printedAnything = false;
13938 final long now = SystemClock.uptimeMillis();
13940 for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
13941 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
13942 = mAssociations.valueAt(i1);
13943 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
13944 SparseArray<ArrayMap<String, Association>> sourceUids
13945 = targetComponents.valueAt(i2);
13946 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
13947 ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
13948 for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
13949 Association ass = sourceProcesses.valueAt(i4);
13950 if (dumpPackage != null) {
13951 if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
13952 && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
13956 printedAnything = true;
13958 pw.print(ass.mTargetProcess);
13960 UserHandle.formatUid(pw, ass.mTargetUid);
13962 pw.print(ass.mSourceProcess);
13964 UserHandle.formatUid(pw, ass.mSourceUid);
13967 pw.print(ass.mTargetComponent.flattenToShortString());
13970 long dur = ass.mTime;
13971 if (ass.mNesting > 0) {
13972 dur += now - ass.mStartTime;
13974 TimeUtils.formatDuration(dur, pw);
13976 pw.print(ass.mCount);
13977 pw.println(" times)");
13978 if (ass.mNesting > 0) {
13980 pw.print(" Currently active: ");
13981 TimeUtils.formatDuration(now - ass.mStartTime, pw);
13990 if (!printedAnything) {
13991 pw.println(" (nothing)");
13995 boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
13996 String header, boolean needSep) {
13997 boolean printed = false;
13998 int whichAppId = -1;
13999 if (dumpPackage != null) {
14001 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14003 whichAppId = UserHandle.getAppId(info.uid);
14004 } catch (NameNotFoundException e) {
14005 e.printStackTrace();
14008 for (int i=0; i<uids.size(); i++) {
14009 UidRecord uidRec = uids.valueAt(i);
14010 if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14019 pw.println(header);
14022 pw.print(" UID "); UserHandle.formatUid(pw, uidRec.uid);
14023 pw.print(": "); pw.println(uidRec);
14028 void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14029 int opti, boolean dumpAll, String dumpPackage) {
14030 boolean needSep = false;
14031 boolean printedAnything = false;
14034 pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14037 final int NP = mProcessNames.getMap().size();
14038 for (int ip=0; ip<NP; ip++) {
14039 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14040 final int NA = procs.size();
14041 for (int ia=0; ia<NA; ia++) {
14042 ProcessRecord r = procs.valueAt(ia);
14043 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14047 pw.println(" All known processes:");
14049 printedAnything = true;
14051 pw.print(r.persistent ? " *PERS*" : " *APP*");
14052 pw.print(" UID "); pw.print(procs.keyAt(ia));
14053 pw.print(" "); pw.println(r);
14055 if (r.persistent) {
14062 if (mIsolatedProcesses.size() > 0) {
14063 boolean printed = false;
14064 for (int i=0; i<mIsolatedProcesses.size(); i++) {
14065 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14066 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14073 pw.println(" Isolated process list (sorted by uid):");
14074 printedAnything = true;
14078 pw.println(String.format("%sIsolated #%2d: %s",
14079 " ", i, r.toString()));
14083 if (mActiveUids.size() > 0) {
14084 if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14085 printedAnything = needSep = true;
14088 if (mValidateUids.size() > 0) {
14089 if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14090 printedAnything = needSep = true;
14094 if (mLruProcesses.size() > 0) {
14098 pw.print(" Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14099 pw.print(" total, non-act at ");
14100 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14101 pw.print(", non-svc at ");
14102 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14104 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", false, dumpPackage);
14106 printedAnything = true;
14109 if (dumpAll || dumpPackage != null) {
14110 synchronized (mPidsSelfLocked) {
14111 boolean printed = false;
14112 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14113 ProcessRecord r = mPidsSelfLocked.valueAt(i);
14114 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14118 if (needSep) pw.println();
14120 pw.println(" PID mappings:");
14122 printedAnything = true;
14124 pw.print(" PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14125 pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14130 if (mForegroundProcesses.size() > 0) {
14131 synchronized (mPidsSelfLocked) {
14132 boolean printed = false;
14133 for (int i=0; i<mForegroundProcesses.size(); i++) {
14134 ProcessRecord r = mPidsSelfLocked.get(
14135 mForegroundProcesses.valueAt(i).pid);
14136 if (dumpPackage != null && (r == null
14137 || !r.pkgList.containsKey(dumpPackage))) {
14141 if (needSep) pw.println();
14143 pw.println(" Foreground Processes:");
14145 printedAnything = true;
14147 pw.print(" PID #"); pw.print(mForegroundProcesses.keyAt(i));
14148 pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14153 if (mPersistentStartingProcesses.size() > 0) {
14154 if (needSep) pw.println();
14156 printedAnything = true;
14157 pw.println(" Persisent processes that are starting:");
14158 dumpProcessList(pw, this, mPersistentStartingProcesses, " ",
14159 "Starting Norm", "Restarting PERS", dumpPackage);
14162 if (mRemovedProcesses.size() > 0) {
14163 if (needSep) pw.println();
14165 printedAnything = true;
14166 pw.println(" Processes that are being removed:");
14167 dumpProcessList(pw, this, mRemovedProcesses, " ",
14168 "Removed Norm", "Removed PERS", dumpPackage);
14171 if (mProcessesOnHold.size() > 0) {
14172 if (needSep) pw.println();
14174 printedAnything = true;
14175 pw.println(" Processes that are on old until the system is ready:");
14176 dumpProcessList(pw, this, mProcessesOnHold, " ",
14177 "OnHold Norm", "OnHold PERS", dumpPackage);
14180 needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14182 needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14184 printedAnything = true;
14187 if (dumpPackage == null) {
14190 mUserController.dump(pw, dumpAll);
14192 if (mHomeProcess != null && (dumpPackage == null
14193 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14198 pw.println(" mHomeProcess: " + mHomeProcess);
14200 if (mPreviousProcess != null && (dumpPackage == null
14201 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14206 pw.println(" mPreviousProcess: " + mPreviousProcess);
14209 StringBuilder sb = new StringBuilder(128);
14210 sb.append(" mPreviousProcessVisibleTime: ");
14211 TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14214 if (mHeavyWeightProcess != null && (dumpPackage == null
14215 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14220 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14222 if (dumpPackage == null) {
14223 pw.println(" mConfiguration: " + mConfiguration);
14226 pw.println(" mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14227 if (mCompatModePackages.getPackages().size() > 0) {
14228 boolean printed = false;
14229 for (Map.Entry<String, Integer> entry
14230 : mCompatModePackages.getPackages().entrySet()) {
14231 String pkg = entry.getKey();
14232 int mode = entry.getValue();
14233 if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14237 pw.println(" mScreenCompatPackages:");
14240 pw.print(" "); pw.print(pkg); pw.print(": ");
14241 pw.print(mode); pw.println();
14245 if (dumpPackage == null) {
14246 pw.println(" mWakefulness="
14247 + PowerManagerInternal.wakefulnessToString(mWakefulness));
14248 pw.println(" mSleepTokens=" + mSleepTokens);
14249 pw.println(" mSleeping=" + mSleeping + " mLockScreenShown="
14250 + lockScreenShownToString());
14251 pw.println(" mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14252 if (mRunningVoice != null) {
14253 pw.println(" mRunningVoice=" + mRunningVoice);
14254 pw.println(" mVoiceWakeLock" + mVoiceWakeLock);
14257 if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14258 || mOrigWaitForDebugger) {
14259 if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14260 || dumpPackage.equals(mOrigDebugApp)) {
14265 pw.println(" mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14266 + " mDebugTransient=" + mDebugTransient
14267 + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14270 if (mCurAppTimeTracker != null) {
14271 mCurAppTimeTracker.dumpWithHeader(pw, " ", true);
14273 if (mMemWatchProcesses.getMap().size() > 0) {
14274 pw.println(" Mem watch processes:");
14275 final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14276 = mMemWatchProcesses.getMap();
14277 for (int i=0; i<procs.size(); i++) {
14278 final String proc = procs.keyAt(i);
14279 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14280 for (int j=0; j<uids.size(); j++) {
14285 StringBuilder sb = new StringBuilder();
14286 sb.append(" ").append(proc).append('/');
14287 UserHandle.formatUid(sb, uids.keyAt(j));
14288 Pair<Long, String> val = uids.valueAt(j);
14289 sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14290 if (val.second != null) {
14291 sb.append(", report to ").append(val.second);
14293 pw.println(sb.toString());
14296 pw.print(" mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14297 pw.print(" mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14298 pw.print(" mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14299 pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14301 if (mTrackAllocationApp != null) {
14302 if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14307 pw.println(" mTrackAllocationApp=" + mTrackAllocationApp);
14310 if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14311 || mProfileFd != null) {
14312 if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14317 pw.println(" mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14318 pw.println(" mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14319 pw.println(" mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14320 + mAutoStopProfiler);
14321 pw.println(" mProfileType=" + mProfileType);
14324 if (mNativeDebuggingApp != null) {
14325 if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14330 pw.println(" mNativeDebuggingApp=" + mNativeDebuggingApp);
14333 if (dumpPackage == null) {
14334 if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14335 pw.println(" mAlwaysFinishActivities=" + mAlwaysFinishActivities
14336 + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14338 if (mController != null) {
14339 pw.println(" mController=" + mController
14340 + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14343 pw.println(" Total persistent processes: " + numPers);
14344 pw.println(" mProcessesReady=" + mProcessesReady
14345 + " mSystemReady=" + mSystemReady
14346 + " mBooted=" + mBooted
14347 + " mFactoryTest=" + mFactoryTest);
14348 pw.println(" mBooting=" + mBooting
14349 + " mCallFinishBooting=" + mCallFinishBooting
14350 + " mBootAnimationComplete=" + mBootAnimationComplete);
14351 pw.print(" mLastPowerCheckRealtime=");
14352 TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14354 pw.print(" mLastPowerCheckUptime=");
14355 TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14357 pw.println(" mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14358 pw.println(" mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14359 pw.println(" mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14360 pw.println(" mNumNonCachedProcs=" + mNumNonCachedProcs
14361 + " (" + mLruProcesses.size() + " total)"
14362 + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14363 + " mNumServiceProcs=" + mNumServiceProcs
14364 + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14365 pw.println(" mAllowLowerMemLevel=" + mAllowLowerMemLevel
14366 + " mLastMemoryLevel" + mLastMemoryLevel
14367 + " mLastNumProcesses" + mLastNumProcesses);
14368 long now = SystemClock.uptimeMillis();
14369 pw.print(" mLastIdleTime=");
14370 TimeUtils.formatDuration(now, mLastIdleTime, pw);
14371 pw.print(" mLowRamSinceLastIdle=");
14372 TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14377 if (!printedAnything) {
14378 pw.println(" (nothing)");
14382 boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14383 int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14384 if (mProcessesToGc.size() > 0) {
14385 boolean printed = false;
14386 long now = SystemClock.uptimeMillis();
14387 for (int i=0; i<mProcessesToGc.size(); i++) {
14388 ProcessRecord proc = mProcessesToGc.get(i);
14389 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14393 if (needSep) pw.println();
14395 pw.println(" Processes that are waiting to GC:");
14398 pw.print(" Process "); pw.println(proc);
14399 pw.print(" lowMem="); pw.print(proc.reportLowMemory);
14400 pw.print(", last gced=");
14401 pw.print(now-proc.lastRequestedGc);
14402 pw.print(" ms ago, last lowMem=");
14403 pw.print(now-proc.lastLowMemory);
14404 pw.println(" ms ago");
14411 void printOomLevel(PrintWriter pw, String name, int adj) {
14415 if (adj < 10) pw.print(' ');
14417 if (adj > -10) pw.print(' ');
14423 pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14427 boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14428 int opti, boolean dumpAll) {
14429 boolean needSep = false;
14431 if (mLruProcesses.size() > 0) {
14432 if (needSep) pw.println();
14434 pw.println(" OOM levels:");
14435 printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14436 printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14437 printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14438 printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14439 printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14440 printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14441 printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
14442 printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
14443 printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
14444 printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
14445 printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
14446 printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
14447 printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
14448 printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
14450 if (needSep) pw.println();
14451 pw.print(" Process OOM control ("); pw.print(mLruProcesses.size());
14452 pw.print(" total, non-act at ");
14453 pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14454 pw.print(", non-svc at ");
14455 pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14457 dumpProcessOomList(pw, this, mLruProcesses, " ", "Proc", "PERS", true, null);
14461 dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
14464 pw.println(" mHomeProcess: " + mHomeProcess);
14465 pw.println(" mPreviousProcess: " + mPreviousProcess);
14466 if (mHeavyWeightProcess != null) {
14467 pw.println(" mHeavyWeightProcess: " + mHeavyWeightProcess);
14474 * There are three ways to call this:
14475 * - no provider specified: dump all the providers
14476 * - a flattened component name that matched an existing provider was specified as the
14477 * first arg: dump that one provider
14478 * - the first arg isn't the flattened component name of an existing provider:
14479 * dump all providers whose component contains the first arg as a substring
14481 protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14482 int opti, boolean dumpAll) {
14483 return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
14486 static class ItemMatcher {
14487 ArrayList<ComponentName> components;
14488 ArrayList<String> strings;
14489 ArrayList<Integer> objects;
14496 void build(String name) {
14497 ComponentName componentName = ComponentName.unflattenFromString(name);
14498 if (componentName != null) {
14499 if (components == null) {
14500 components = new ArrayList<ComponentName>();
14502 components.add(componentName);
14506 // Not a '/' separated full component name; maybe an object ID?
14508 objectId = Integer.parseInt(name, 16);
14509 if (objects == null) {
14510 objects = new ArrayList<Integer>();
14512 objects.add(objectId);
14514 } catch (RuntimeException e) {
14515 // Not an integer; just do string match.
14516 if (strings == null) {
14517 strings = new ArrayList<String>();
14525 int build(String[] args, int opti) {
14526 for (; opti<args.length; opti++) {
14527 String name = args[opti];
14528 if ("--".equals(name)) {
14536 boolean match(Object object, ComponentName comp) {
14540 if (components != null) {
14541 for (int i=0; i<components.size(); i++) {
14542 if (components.get(i).equals(comp)) {
14547 if (objects != null) {
14548 for (int i=0; i<objects.size(); i++) {
14549 if (System.identityHashCode(object) == objects.get(i)) {
14554 if (strings != null) {
14555 String flat = comp.flattenToString();
14556 for (int i=0; i<strings.size(); i++) {
14557 if (flat.contains(strings.get(i))) {
14567 * There are three things that cmd can be:
14568 * - a flattened component name that matches an existing activity
14569 * - the cmd arg isn't the flattened component name of an existing activity:
14570 * dump all activity whose component contains the cmd as a substring
14571 * - A hex number of the ActivityRecord object instance.
14573 protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
14574 int opti, boolean dumpAll) {
14575 ArrayList<ActivityRecord> activities;
14577 synchronized (this) {
14578 activities = mStackSupervisor.getDumpActivitiesLocked(name);
14581 if (activities.size() <= 0) {
14585 String[] newArgs = new String[args.length - opti];
14586 System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14588 TaskRecord lastTask = null;
14589 boolean needSep = false;
14590 for (int i=activities.size()-1; i>=0; i--) {
14591 ActivityRecord r = activities.get(i);
14596 synchronized (this) {
14597 if (lastTask != r.task) {
14599 pw.print("TASK "); pw.print(lastTask.affinity);
14600 pw.print(" id="); pw.println(lastTask.taskId);
14602 lastTask.dump(pw, " ");
14606 dumpActivity(" ", fd, pw, activities.get(i), newArgs, dumpAll);
14612 * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
14613 * there is a thread associated with the activity.
14615 private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
14616 final ActivityRecord r, String[] args, boolean dumpAll) {
14617 String innerPrefix = prefix + " ";
14618 synchronized (this) {
14619 pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
14620 pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
14622 if (r.app != null) pw.println(r.app.pid);
14623 else pw.println("(not running)");
14625 r.dump(pw, innerPrefix);
14628 if (r.app != null && r.app.thread != null) {
14629 // flush anything that is already in the PrintWriter since the thread is going
14630 // to write to the file descriptor directly
14633 TransferPipe tp = new TransferPipe();
14635 r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
14636 r.appToken, innerPrefix, args);
14641 } catch (IOException e) {
14642 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
14643 } catch (RemoteException e) {
14644 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
14649 void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14650 int opti, boolean dumpAll, String dumpPackage) {
14651 boolean needSep = false;
14652 boolean onlyHistory = false;
14653 boolean printedAnything = false;
14655 if ("history".equals(dumpPackage)) {
14656 if (opti < args.length && "-s".equals(args[opti])) {
14659 onlyHistory = true;
14660 dumpPackage = null;
14663 pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
14664 if (!onlyHistory && dumpAll) {
14665 if (mRegisteredReceivers.size() > 0) {
14666 boolean printed = false;
14667 Iterator it = mRegisteredReceivers.values().iterator();
14668 while (it.hasNext()) {
14669 ReceiverList r = (ReceiverList)it.next();
14670 if (dumpPackage != null && (r.app == null ||
14671 !dumpPackage.equals(r.app.info.packageName))) {
14675 pw.println(" Registered Receivers:");
14678 printedAnything = true;
14680 pw.print(" * "); pw.println(r);
14685 if (mReceiverResolver.dump(pw, needSep ?
14686 "\n Receiver Resolver Table:" : " Receiver Resolver Table:",
14687 " ", dumpPackage, false, false)) {
14689 printedAnything = true;
14693 for (BroadcastQueue q : mBroadcastQueues) {
14694 needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
14695 printedAnything |= needSep;
14700 if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
14701 for (int user=0; user<mStickyBroadcasts.size(); user++) {
14706 printedAnything = true;
14707 pw.print(" Sticky broadcasts for user ");
14708 pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
14709 StringBuilder sb = new StringBuilder(128);
14710 for (Map.Entry<String, ArrayList<Intent>> ent
14711 : mStickyBroadcasts.valueAt(user).entrySet()) {
14712 pw.print(" * Sticky action "); pw.print(ent.getKey());
14715 ArrayList<Intent> intents = ent.getValue();
14716 final int N = intents.size();
14717 for (int i=0; i<N; i++) {
14719 sb.append(" Intent: ");
14720 intents.get(i).toShortString(sb, false, true, false, false);
14721 pw.println(sb.toString());
14722 Bundle bundle = intents.get(i).getExtras();
14723 if (bundle != null) {
14725 pw.println(bundle.toString());
14735 if (!onlyHistory && dumpAll) {
14737 for (BroadcastQueue queue : mBroadcastQueues) {
14738 pw.println(" mBroadcastsScheduled [" + queue.mQueueName + "]="
14739 + queue.mBroadcastsScheduled);
14741 pw.println(" mHandler:");
14742 mHandler.dump(new PrintWriterPrinter(pw), " ");
14744 printedAnything = true;
14747 if (!printedAnything) {
14748 pw.println(" (nothing)");
14752 void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14753 int opti, boolean dumpAll, String dumpPackage) {
14755 boolean printedAnything = false;
14757 ItemMatcher matcher = new ItemMatcher();
14758 matcher.build(args, opti);
14760 pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
14762 needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
14763 printedAnything |= needSep;
14765 if (mLaunchingProviders.size() > 0) {
14766 boolean printed = false;
14767 for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
14768 ContentProviderRecord r = mLaunchingProviders.get(i);
14769 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
14773 if (needSep) pw.println();
14775 pw.println(" Launching content providers:");
14777 printedAnything = true;
14779 pw.print(" Launching #"); pw.print(i); pw.print(": ");
14784 if (!printedAnything) {
14785 pw.println(" (nothing)");
14789 void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14790 int opti, boolean dumpAll, String dumpPackage) {
14791 boolean needSep = false;
14792 boolean printedAnything = false;
14794 pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
14796 if (mGrantedUriPermissions.size() > 0) {
14797 boolean printed = false;
14799 if (dumpPackage != null) {
14801 dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
14802 MATCH_UNINSTALLED_PACKAGES, 0);
14803 } catch (NameNotFoundException e) {
14807 for (int i=0; i<mGrantedUriPermissions.size(); i++) {
14808 int uid = mGrantedUriPermissions.keyAt(i);
14809 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
14812 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
14814 if (needSep) pw.println();
14816 pw.println(" Granted Uri Permissions:");
14818 printedAnything = true;
14820 pw.print(" * UID "); pw.print(uid); pw.println(" holds:");
14821 for (UriPermission perm : perms.values()) {
14822 pw.print(" "); pw.println(perm);
14824 perm.dump(pw, " ");
14830 if (!printedAnything) {
14831 pw.println(" (nothing)");
14835 void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14836 int opti, boolean dumpAll, String dumpPackage) {
14837 boolean printed = false;
14839 pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
14841 if (mIntentSenderRecords.size() > 0) {
14842 Iterator<WeakReference<PendingIntentRecord>> it
14843 = mIntentSenderRecords.values().iterator();
14844 while (it.hasNext()) {
14845 WeakReference<PendingIntentRecord> ref = it.next();
14846 PendingIntentRecord rec = ref != null ? ref.get(): null;
14847 if (dumpPackage != null && (rec == null
14848 || !dumpPackage.equals(rec.key.packageName))) {
14853 pw.print(" * "); pw.println(rec);
14858 pw.print(" * "); pw.println(ref);
14864 pw.println(" (nothing)");
14868 private static final int dumpProcessList(PrintWriter pw,
14869 ActivityManagerService service, List list,
14870 String prefix, String normalLabel, String persistentLabel,
14871 String dumpPackage) {
14873 final int N = list.size()-1;
14874 for (int i=N; i>=0; i--) {
14875 ProcessRecord r = (ProcessRecord)list.get(i);
14876 if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
14879 pw.println(String.format("%s%s #%2d: %s",
14880 prefix, (r.persistent ? persistentLabel : normalLabel),
14882 if (r.persistent) {
14889 private static final boolean dumpProcessOomList(PrintWriter pw,
14890 ActivityManagerService service, List<ProcessRecord> origList,
14891 String prefix, String normalLabel, String persistentLabel,
14892 boolean inclDetails, String dumpPackage) {
14894 ArrayList<Pair<ProcessRecord, Integer>> list
14895 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
14896 for (int i=0; i<origList.size(); i++) {
14897 ProcessRecord r = origList.get(i);
14898 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14901 list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
14904 if (list.size() <= 0) {
14908 Comparator<Pair<ProcessRecord, Integer>> comparator
14909 = new Comparator<Pair<ProcessRecord, Integer>>() {
14911 public int compare(Pair<ProcessRecord, Integer> object1,
14912 Pair<ProcessRecord, Integer> object2) {
14913 if (object1.first.setAdj != object2.first.setAdj) {
14914 return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
14916 if (object1.first.setProcState != object2.first.setProcState) {
14917 return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
14919 if (object1.second.intValue() != object2.second.intValue()) {
14920 return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
14926 Collections.sort(list, comparator);
14928 final long curRealtime = SystemClock.elapsedRealtime();
14929 final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
14930 final long curUptime = SystemClock.uptimeMillis();
14931 final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
14933 for (int i=list.size()-1; i>=0; i--) {
14934 ProcessRecord r = list.get(i).first;
14935 String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
14937 switch (r.setSchedGroup) {
14938 case ProcessList.SCHED_GROUP_BACKGROUND:
14941 case ProcessList.SCHED_GROUP_DEFAULT:
14944 case ProcessList.SCHED_GROUP_TOP_APP:
14952 if (r.foregroundActivities) {
14954 } else if (r.foregroundServices) {
14959 String procState = ProcessList.makeProcStateString(r.curProcState);
14961 pw.print(r.persistent ? persistentLabel : normalLabel);
14963 int num = (origList.size()-1)-list.get(i).second;
14964 if (num < 10) pw.print(' ');
14969 pw.print(schedGroup);
14971 pw.print(foreground);
14973 pw.print(procState);
14975 if (r.trimMemoryLevel < 10) pw.print(' ');
14976 pw.print(r.trimMemoryLevel);
14978 pw.print(r.toShortString());
14980 pw.print(r.adjType);
14982 if (r.adjSource != null || r.adjTarget != null) {
14985 if (r.adjTarget instanceof ComponentName) {
14986 pw.print(((ComponentName)r.adjTarget).flattenToShortString());
14987 } else if (r.adjTarget != null) {
14988 pw.print(r.adjTarget.toString());
14990 pw.print("{null}");
14993 if (r.adjSource instanceof ProcessRecord) {
14995 pw.print(((ProcessRecord)r.adjSource).toShortString());
14997 } else if (r.adjSource != null) {
14998 pw.println(r.adjSource.toString());
15000 pw.println("{null}");
15006 pw.print("oom: max="); pw.print(r.maxAdj);
15007 pw.print(" curRaw="); pw.print(r.curRawAdj);
15008 pw.print(" setRaw="); pw.print(r.setRawAdj);
15009 pw.print(" cur="); pw.print(r.curAdj);
15010 pw.print(" set="); pw.println(r.setAdj);
15013 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15014 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15015 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15016 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15017 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15021 pw.print("cached="); pw.print(r.cached);
15022 pw.print(" empty="); pw.print(r.empty);
15023 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15025 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15026 if (r.lastWakeTime != 0) {
15028 BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15029 synchronized (stats) {
15030 wtime = stats.getProcessWakeTime(r.info.uid,
15031 r.pid, curRealtime);
15033 long timeUsed = wtime - r.lastWakeTime;
15036 pw.print("keep awake over ");
15037 TimeUtils.formatDuration(realtimeSince, pw);
15038 pw.print(" used ");
15039 TimeUtils.formatDuration(timeUsed, pw);
15041 pw.print((timeUsed*100)/realtimeSince);
15044 if (r.lastCpuTime != 0) {
15045 long timeUsed = r.curCpuTime - r.lastCpuTime;
15048 pw.print("run cpu over ");
15049 TimeUtils.formatDuration(uptimeSince, pw);
15050 pw.print(" used ");
15051 TimeUtils.formatDuration(timeUsed, pw);
15053 pw.print((timeUsed*100)/uptimeSince);
15062 ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15064 ArrayList<ProcessRecord> procs;
15065 synchronized (this) {
15066 if (args != null && args.length > start
15067 && args[start].charAt(0) != '-') {
15068 procs = new ArrayList<ProcessRecord>();
15071 pid = Integer.parseInt(args[start]);
15072 } catch (NumberFormatException e) {
15074 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15075 ProcessRecord proc = mLruProcesses.get(i);
15076 if (proc.pid == pid) {
15078 } else if (allPkgs && proc.pkgList != null
15079 && proc.pkgList.containsKey(args[start])) {
15081 } else if (proc.processName.equals(args[start])) {
15085 if (procs.size() <= 0) {
15089 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15095 final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15096 PrintWriter pw, String[] args) {
15097 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15098 if (procs == null) {
15099 pw.println("No process found for: " + args[0]);
15103 long uptime = SystemClock.uptimeMillis();
15104 long realtime = SystemClock.elapsedRealtime();
15105 pw.println("Applications Graphics Acceleration Info:");
15106 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15108 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15109 ProcessRecord r = procs.get(i);
15110 if (r.thread != null) {
15111 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15114 TransferPipe tp = new TransferPipe();
15116 r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15121 } catch (IOException e) {
15122 pw.println("Failure while dumping the app: " + r);
15124 } catch (RemoteException e) {
15125 pw.println("Got a RemoteException while dumping the app " + r);
15132 final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15133 ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15134 if (procs == null) {
15135 pw.println("No process found for: " + args[0]);
15139 pw.println("Applications Database Info:");
15141 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15142 ProcessRecord r = procs.get(i);
15143 if (r.thread != null) {
15144 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15147 TransferPipe tp = new TransferPipe();
15149 r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15154 } catch (IOException e) {
15155 pw.println("Failure while dumping the app: " + r);
15157 } catch (RemoteException e) {
15158 pw.println("Got a RemoteException while dumping the app " + r);
15165 final static class MemItem {
15166 final boolean isProc;
15167 final String label;
15168 final String shortLabel;
15170 final long swapPss;
15172 final boolean hasActivities;
15173 ArrayList<MemItem> subitems;
15175 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15176 boolean _hasActivities) {
15179 shortLabel = _shortLabel;
15181 swapPss = _swapPss;
15183 hasActivities = _hasActivities;
15186 public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15189 shortLabel = _shortLabel;
15191 swapPss = _swapPss;
15193 hasActivities = false;
15197 static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15198 ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15199 if (sort && !isCompact) {
15200 Collections.sort(items, new Comparator<MemItem>() {
15202 public int compare(MemItem lhs, MemItem rhs) {
15203 if (lhs.pss < rhs.pss) {
15205 } else if (lhs.pss > rhs.pss) {
15213 for (int i=0; i<items.size(); i++) {
15214 MemItem mi = items.get(i);
15217 pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15218 mi.label, stringifyKBSize(mi.swapPss));
15220 pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15222 } else if (mi.isProc) {
15223 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15224 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15225 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15226 pw.println(mi.hasActivities ? ",a" : ",e");
15228 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15229 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15231 if (mi.subitems != null) {
15232 dumpMemItems(pw, prefix + " ", mi.shortLabel, mi.subitems,
15233 true, isCompact, dumpSwapPss);
15238 // These are in KB.
15239 static final long[] DUMP_MEM_BUCKETS = new long[] {
15240 5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15241 120*1024, 160*1024, 200*1024,
15242 250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15243 1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15246 static final void appendMemBucket(StringBuilder out, long memKB, String label,
15247 boolean stackLike) {
15248 int start = label.lastIndexOf('.');
15249 if (start >= 0) start++;
15251 int end = label.length();
15252 for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15253 if (DUMP_MEM_BUCKETS[i] >= memKB) {
15254 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15255 out.append(bucket);
15256 out.append(stackLike ? "MB." : "MB ");
15257 out.append(label, start, end);
15261 out.append(memKB/1024);
15262 out.append(stackLike ? "MB." : "MB ");
15263 out.append(label, start, end);
15266 static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15267 ProcessList.NATIVE_ADJ,
15268 ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15269 ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15270 ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15271 ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15272 ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15273 ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MAX_ADJ
15275 static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15277 "System", "Persistent", "Persistent Service", "Foreground",
15278 "Visible", "Perceptible",
15279 "Heavy Weight", "Backup",
15280 "A Services", "Home",
15281 "Previous", "B Services", "Cached"
15283 static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15285 "sys", "pers", "persvc", "fore",
15288 "servicea", "home",
15289 "prev", "serviceb", "cached"
15292 private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15293 long realtime, boolean isCheckinRequest, boolean isCompact) {
15295 pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15297 if (isCheckinRequest || isCompact) {
15298 // short checkin version
15299 pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15301 pw.println("Applications Memory Usage (in Kilobytes):");
15302 pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15306 private static final int KSM_SHARED = 0;
15307 private static final int KSM_SHARING = 1;
15308 private static final int KSM_UNSHARED = 2;
15309 private static final int KSM_VOLATILE = 3;
15311 private final long[] getKsmInfo() {
15312 long[] longOut = new long[4];
15313 final int[] SINGLE_LONG_FORMAT = new int[] {
15314 Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15316 long[] longTmp = new long[1];
15317 Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15318 SINGLE_LONG_FORMAT, null, longTmp, null);
15319 longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15321 Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15322 SINGLE_LONG_FORMAT, null, longTmp, null);
15323 longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15325 Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15326 SINGLE_LONG_FORMAT, null, longTmp, null);
15327 longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15329 Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15330 SINGLE_LONG_FORMAT, null, longTmp, null);
15331 longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15335 private static String stringifySize(long size, int order) {
15336 Locale locale = Locale.US;
15339 return String.format(locale, "%,13d", size);
15341 return String.format(locale, "%,9dK", size / 1024);
15343 return String.format(locale, "%,5dM", size / 1024 / 1024);
15344 case 1024 * 1024 * 1024:
15345 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15347 throw new IllegalArgumentException("Invalid size order");
15351 private static String stringifyKBSize(long size) {
15352 return stringifySize(size * 1024, 1024);
15355 // Update this version number in case you change the 'compact' format
15356 private static final int MEMINFO_COMPACT_VERSION = 1;
15358 final void dumpApplicationMemoryUsage(FileDescriptor fd,
15359 PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15360 boolean dumpDetails = false;
15361 boolean dumpFullDetails = false;
15362 boolean dumpDalvik = false;
15363 boolean dumpSummaryOnly = false;
15364 boolean dumpUnreachable = false;
15365 boolean oomOnly = false;
15366 boolean isCompact = false;
15367 boolean localOnly = false;
15368 boolean packages = false;
15369 boolean isCheckinRequest = false;
15370 boolean dumpSwapPss = false;
15373 while (opti < args.length) {
15374 String opt = args[opti];
15375 if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15379 if ("-a".equals(opt)) {
15380 dumpDetails = true;
15381 dumpFullDetails = true;
15383 dumpSwapPss = true;
15384 } else if ("-d".equals(opt)) {
15386 } else if ("-c".equals(opt)) {
15388 } else if ("-s".equals(opt)) {
15389 dumpDetails = true;
15390 dumpSummaryOnly = true;
15391 } else if ("-S".equals(opt)) {
15392 dumpSwapPss = true;
15393 } else if ("--unreachable".equals(opt)) {
15394 dumpUnreachable = true;
15395 } else if ("--oom".equals(opt)) {
15397 } else if ("--local".equals(opt)) {
15399 } else if ("--package".equals(opt)) {
15401 } else if ("--checkin".equals(opt)) {
15402 isCheckinRequest = true;
15404 } else if ("-h".equals(opt)) {
15405 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
15406 pw.println(" -a: include all available information for each process.");
15407 pw.println(" -d: include dalvik details.");
15408 pw.println(" -c: dump in a compact machine-parseable representation.");
15409 pw.println(" -s: dump only summary of application memory usage.");
15410 pw.println(" -S: dump also SwapPss.");
15411 pw.println(" --oom: only show processes organized by oom adj.");
15412 pw.println(" --local: only collect details locally, don't call process.");
15413 pw.println(" --package: interpret process arg as package, dumping all");
15414 pw.println(" processes that have loaded that package.");
15415 pw.println(" --checkin: dump data for a checkin");
15416 pw.println("If [process] is specified it can be the name or ");
15417 pw.println("pid of a specific process to dump.");
15420 pw.println("Unknown argument: " + opt + "; use -h for help");
15424 long uptime = SystemClock.uptimeMillis();
15425 long realtime = SystemClock.elapsedRealtime();
15426 final long[] tmpLong = new long[1];
15428 ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
15429 if (procs == null) {
15430 // No Java processes. Maybe they want to print a native process.
15431 if (args != null && args.length > opti
15432 && args[opti].charAt(0) != '-') {
15433 ArrayList<ProcessCpuTracker.Stats> nativeProcs
15434 = new ArrayList<ProcessCpuTracker.Stats>();
15435 updateCpuStatsNow();
15438 findPid = Integer.parseInt(args[opti]);
15439 } catch (NumberFormatException e) {
15441 synchronized (mProcessCpuTracker) {
15442 final int N = mProcessCpuTracker.countStats();
15443 for (int i=0; i<N; i++) {
15444 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15445 if (st.pid == findPid || (st.baseName != null
15446 && st.baseName.equals(args[opti]))) {
15447 nativeProcs.add(st);
15451 if (nativeProcs.size() > 0) {
15452 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
15454 Debug.MemoryInfo mi = null;
15455 for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
15456 final ProcessCpuTracker.Stats r = nativeProcs.get(i);
15457 final int pid = r.pid;
15458 if (!isCheckinRequest && dumpDetails) {
15459 pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
15462 mi = new Debug.MemoryInfo();
15464 if (dumpDetails || (!brief && !oomOnly)) {
15465 Debug.getMemoryInfo(pid, mi);
15467 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15468 mi.dalvikPrivateDirty = (int)tmpLong[0];
15470 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15471 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
15472 if (isCheckinRequest) {
15479 pw.println("No process found for: " + args[opti]);
15483 if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
15484 dumpDetails = true;
15487 dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
15489 String[] innerArgs = new String[args.length-opti];
15490 System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
15492 ArrayList<MemItem> procMems = new ArrayList<MemItem>();
15493 final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
15494 long nativePss = 0;
15495 long nativeSwapPss = 0;
15496 long dalvikPss = 0;
15497 long dalvikSwapPss = 0;
15498 long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15500 long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
15503 long otherSwapPss = 0;
15504 long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15505 long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
15507 long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15508 long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
15509 ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
15510 new ArrayList[DUMP_MEM_OOM_LABEL.length];
15513 long totalSwapPss = 0;
15514 long cachedPss = 0;
15515 long cachedSwapPss = 0;
15516 boolean hasSwapPss = false;
15518 Debug.MemoryInfo mi = null;
15519 for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15520 final ProcessRecord r = procs.get(i);
15521 final IApplicationThread thread;
15524 final boolean hasActivities;
15525 synchronized (this) {
15528 oomAdj = r.getSetAdjWithServices();
15529 hasActivities = r.activities.size() > 0;
15531 if (thread != null) {
15532 if (!isCheckinRequest && dumpDetails) {
15533 pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
15536 mi = new Debug.MemoryInfo();
15538 if (dumpDetails || (!brief && !oomOnly)) {
15539 Debug.getMemoryInfo(pid, mi);
15540 hasSwapPss = mi.hasSwappedOutPss;
15542 mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
15543 mi.dalvikPrivateDirty = (int)tmpLong[0];
15547 ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
15548 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
15549 if (isCheckinRequest) {
15555 thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
15556 dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
15557 } catch (RemoteException e) {
15558 if (!isCheckinRequest) {
15559 pw.println("Got RemoteException!");
15566 final long myTotalPss = mi.getTotalPss();
15567 final long myTotalUss = mi.getTotalUss();
15568 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15570 synchronized (this) {
15571 if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
15572 // Record this for posterity if the process has been stable.
15573 r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
15577 if (!isCheckinRequest && mi != null) {
15578 totalPss += myTotalPss;
15579 totalSwapPss += myTotalSwapPss;
15580 MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
15581 (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
15582 myTotalSwapPss, pid, hasActivities);
15583 procMems.add(pssItem);
15584 procMemsMap.put(pid, pssItem);
15586 nativePss += mi.nativePss;
15587 nativeSwapPss += mi.nativeSwappedOutPss;
15588 dalvikPss += mi.dalvikPss;
15589 dalvikSwapPss += mi.dalvikSwappedOutPss;
15590 for (int j=0; j<dalvikSubitemPss.length; j++) {
15591 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15592 dalvikSubitemSwapPss[j] +=
15593 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15595 otherPss += mi.otherPss;
15596 otherSwapPss += mi.otherSwappedOutPss;
15597 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15598 long mem = mi.getOtherPss(j);
15601 mem = mi.getOtherSwappedOutPss(j);
15602 miscSwapPss[j] += mem;
15603 otherSwapPss -= mem;
15606 if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15607 cachedPss += myTotalPss;
15608 cachedSwapPss += myTotalSwapPss;
15611 for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
15612 if (oomAdj <= DUMP_MEM_OOM_ADJ[oomIndex]
15613 || oomIndex == (oomPss.length-1)) {
15614 oomPss[oomIndex] += myTotalPss;
15615 oomSwapPss[oomIndex] += myTotalSwapPss;
15616 if (oomProcs[oomIndex] == null) {
15617 oomProcs[oomIndex] = new ArrayList<MemItem>();
15619 oomProcs[oomIndex].add(pssItem);
15627 long nativeProcTotalPss = 0;
15629 if (!isCheckinRequest && procs.size() > 1 && !packages) {
15630 // If we are showing aggregations, also look for native processes to
15631 // include so that our aggregations are more accurate.
15632 updateCpuStatsNow();
15634 synchronized (mProcessCpuTracker) {
15635 final int N = mProcessCpuTracker.countStats();
15636 for (int i=0; i<N; i++) {
15637 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15638 if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
15640 mi = new Debug.MemoryInfo();
15642 if (!brief && !oomOnly) {
15643 Debug.getMemoryInfo(st.pid, mi);
15645 mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
15646 mi.nativePrivateDirty = (int)tmpLong[0];
15649 final long myTotalPss = mi.getTotalPss();
15650 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
15651 totalPss += myTotalPss;
15652 nativeProcTotalPss += myTotalPss;
15654 MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
15655 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
15656 procMems.add(pssItem);
15658 nativePss += mi.nativePss;
15659 nativeSwapPss += mi.nativeSwappedOutPss;
15660 dalvikPss += mi.dalvikPss;
15661 dalvikSwapPss += mi.dalvikSwappedOutPss;
15662 for (int j=0; j<dalvikSubitemPss.length; j++) {
15663 dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15664 dalvikSubitemSwapPss[j] +=
15665 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
15667 otherPss += mi.otherPss;
15668 otherSwapPss += mi.otherSwappedOutPss;
15669 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15670 long mem = mi.getOtherPss(j);
15673 mem = mi.getOtherSwappedOutPss(j);
15674 miscSwapPss[j] += mem;
15675 otherSwapPss -= mem;
15677 oomPss[0] += myTotalPss;
15678 oomSwapPss[0] += myTotalSwapPss;
15679 if (oomProcs[0] == null) {
15680 oomProcs[0] = new ArrayList<MemItem>();
15682 oomProcs[0].add(pssItem);
15687 ArrayList<MemItem> catMems = new ArrayList<MemItem>();
15689 catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
15690 final MemItem dalvikItem =
15691 new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
15692 if (dalvikSubitemPss.length > 0) {
15693 dalvikItem.subitems = new ArrayList<MemItem>();
15694 for (int j=0; j<dalvikSubitemPss.length; j++) {
15695 final String name = Debug.MemoryInfo.getOtherLabel(
15696 Debug.MemoryInfo.NUM_OTHER_STATS + j);
15697 dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
15698 dalvikSubitemSwapPss[j], j));
15701 catMems.add(dalvikItem);
15702 catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
15703 for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
15704 String label = Debug.MemoryInfo.getOtherLabel(j);
15705 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
15708 ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
15709 for (int j=0; j<oomPss.length; j++) {
15710 if (oomPss[j] != 0) {
15711 String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
15712 : DUMP_MEM_OOM_LABEL[j];
15713 MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
15714 DUMP_MEM_OOM_ADJ[j]);
15715 item.subitems = oomProcs[j];
15720 dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
15721 if (!brief && !oomOnly && !isCompact) {
15723 pw.println("Total PSS by process:");
15724 dumpMemItems(pw, " ", "proc", procMems, true, isCompact, dumpSwapPss);
15728 pw.println("Total PSS by OOM adjustment:");
15730 dumpMemItems(pw, " ", "oom", oomMems, false, isCompact, dumpSwapPss);
15731 if (!brief && !oomOnly) {
15732 PrintWriter out = categoryPw != null ? categoryPw : pw;
15735 out.println("Total PSS by category:");
15737 dumpMemItems(out, " ", "cat", catMems, true, isCompact, dumpSwapPss);
15742 MemInfoReader memInfo = new MemInfoReader();
15743 memInfo.readMemInfo();
15744 if (nativeProcTotalPss > 0) {
15745 synchronized (this) {
15746 final long cachedKb = memInfo.getCachedSizeKb();
15747 final long freeKb = memInfo.getFreeSizeKb();
15748 final long zramKb = memInfo.getZramTotalSizeKb();
15749 final long kernelKb = memInfo.getKernelUsedSizeKb();
15750 EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
15751 kernelKb*1024, nativeProcTotalPss*1024);
15752 mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
15753 nativeProcTotalPss);
15758 pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
15759 pw.print(" (status ");
15760 switch (mLastMemoryLevel) {
15761 case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
15762 pw.println("normal)");
15764 case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
15765 pw.println("moderate)");
15767 case ProcessStats.ADJ_MEM_FACTOR_LOW:
15768 pw.println("low)");
15770 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
15771 pw.println("critical)");
15774 pw.print(mLastMemoryLevel);
15778 pw.print(" Free RAM: ");
15779 pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
15780 + memInfo.getFreeSizeKb()));
15782 pw.print(stringifyKBSize(cachedPss));
15783 pw.print(" cached pss + ");
15784 pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
15785 pw.print(" cached kernel + ");
15786 pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
15787 pw.println(" free)");
15789 pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
15790 pw.print(cachedPss + memInfo.getCachedSizeKb()
15791 + memInfo.getFreeSizeKb()); pw.print(",");
15792 pw.println(totalPss - cachedPss);
15795 long lostRAM = memInfo.getTotalSizeKb()
15796 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
15797 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
15799 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
15800 + memInfo.getKernelUsedSizeKb())); pw.print(" (");
15801 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
15802 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
15803 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
15805 pw.print("lostram,"); pw.println(lostRAM);
15808 if (memInfo.getZramTotalSizeKb() != 0) {
15810 pw.print(" ZRAM: ");
15811 pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
15812 pw.print(" physical used for ");
15813 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
15814 - memInfo.getSwapFreeSizeKb()));
15815 pw.print(" in swap (");
15816 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
15817 pw.println(" total swap)");
15819 pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
15820 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
15821 pw.println(memInfo.getSwapFreeSizeKb());
15824 final long[] ksm = getKsmInfo();
15826 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
15827 || ksm[KSM_VOLATILE] != 0) {
15828 pw.print(" KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
15829 pw.print(" saved from shared ");
15830 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
15831 pw.print(" "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
15832 pw.print(" unshared; ");
15833 pw.print(stringifyKBSize(
15834 ksm[KSM_VOLATILE])); pw.println(" volatile");
15836 pw.print(" Tuning: ");
15837 pw.print(ActivityManager.staticGetMemoryClass());
15838 pw.print(" (large ");
15839 pw.print(ActivityManager.staticGetLargeMemoryClass());
15840 pw.print("), oom ");
15841 pw.print(stringifySize(
15842 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
15843 pw.print(", restore limit ");
15844 pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
15845 if (ActivityManager.isLowRamDeviceStatic()) {
15846 pw.print(" (low-ram)");
15848 if (ActivityManager.isHighEndGfx()) {
15849 pw.print(" (high-end-gfx)");
15853 pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
15854 pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
15855 pw.print(","); pw.println(ksm[KSM_VOLATILE]);
15856 pw.print("tuning,");
15857 pw.print(ActivityManager.staticGetMemoryClass());
15859 pw.print(ActivityManager.staticGetLargeMemoryClass());
15861 pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
15862 if (ActivityManager.isLowRamDeviceStatic()) {
15863 pw.print(",low-ram");
15865 if (ActivityManager.isHighEndGfx()) {
15866 pw.print(",high-end-gfx");
15874 private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
15875 long memtrack, String name) {
15877 sb.append(ProcessList.makeOomAdjString(oomAdj));
15879 sb.append(ProcessList.makeProcStateString(procState));
15881 ProcessList.appendRamKb(sb, pss);
15884 if (memtrack > 0) {
15886 sb.append(stringifyKBSize(memtrack));
15887 sb.append(" memtrack)");
15891 private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
15892 appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
15893 sb.append(" (pid ");
15896 sb.append(mi.adjType);
15898 if (mi.adjReason != null) {
15900 sb.append(mi.adjReason);
15905 void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
15906 final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
15907 for (int i=0, N=memInfos.size(); i<N; i++) {
15908 ProcessMemInfo mi = memInfos.get(i);
15909 infoMap.put(mi.pid, mi);
15911 updateCpuStatsNow();
15912 long[] memtrackTmp = new long[1];
15913 synchronized (mProcessCpuTracker) {
15914 final int N = mProcessCpuTracker.countStats();
15915 for (int i=0; i<N; i++) {
15916 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
15917 if (st.vsize > 0) {
15918 long pss = Debug.getPss(st.pid, null, memtrackTmp);
15920 if (infoMap.indexOfKey(st.pid) < 0) {
15921 ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
15922 ProcessList.NATIVE_ADJ, -1, "native", null);
15924 mi.memtrack = memtrackTmp[0];
15933 long totalMemtrack = 0;
15934 for (int i=0, N=memInfos.size(); i<N; i++) {
15935 ProcessMemInfo mi = memInfos.get(i);
15937 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
15938 mi.memtrack = memtrackTmp[0];
15940 totalPss += mi.pss;
15941 totalMemtrack += mi.memtrack;
15943 Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
15944 @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
15945 if (lhs.oomAdj != rhs.oomAdj) {
15946 return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
15948 if (lhs.pss != rhs.pss) {
15949 return lhs.pss < rhs.pss ? 1 : -1;
15955 StringBuilder tag = new StringBuilder(128);
15956 StringBuilder stack = new StringBuilder(128);
15957 tag.append("Low on memory -- ");
15958 appendMemBucket(tag, totalPss, "total", false);
15959 appendMemBucket(stack, totalPss, "total", true);
15961 StringBuilder fullNativeBuilder = new StringBuilder(1024);
15962 StringBuilder shortNativeBuilder = new StringBuilder(1024);
15963 StringBuilder fullJavaBuilder = new StringBuilder(1024);
15965 boolean firstLine = true;
15966 int lastOomAdj = Integer.MIN_VALUE;
15967 long extraNativeRam = 0;
15968 long extraNativeMemtrack = 0;
15969 long cachedPss = 0;
15970 for (int i=0, N=memInfos.size(); i<N; i++) {
15971 ProcessMemInfo mi = memInfos.get(i);
15973 if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
15974 cachedPss += mi.pss;
15977 if (mi.oomAdj != ProcessList.NATIVE_ADJ
15978 && (mi.oomAdj < ProcessList.SERVICE_ADJ
15979 || mi.oomAdj == ProcessList.HOME_APP_ADJ
15980 || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
15981 if (lastOomAdj != mi.oomAdj) {
15982 lastOomAdj = mi.oomAdj;
15983 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
15986 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
15991 stack.append("\n\t at ");
15999 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16000 appendMemBucket(tag, mi.pss, mi.name, false);
16002 appendMemBucket(stack, mi.pss, mi.name, true);
16003 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16004 && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16006 for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16007 if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16008 stack.append(DUMP_MEM_OOM_LABEL[k]);
16010 stack.append(DUMP_MEM_OOM_ADJ[k]);
16017 appendMemInfo(fullNativeBuilder, mi);
16018 if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16019 // The short form only has native processes that are >= 512K.
16020 if (mi.pss >= 512) {
16021 appendMemInfo(shortNativeBuilder, mi);
16023 extraNativeRam += mi.pss;
16024 extraNativeMemtrack += mi.memtrack;
16027 // Short form has all other details, but if we have collected RAM
16028 // from smaller native processes let's dump a summary of that.
16029 if (extraNativeRam > 0) {
16030 appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16031 -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16032 shortNativeBuilder.append('\n');
16033 extraNativeRam = 0;
16035 appendMemInfo(fullJavaBuilder, mi);
16039 fullJavaBuilder.append(" ");
16040 ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16041 fullJavaBuilder.append(": TOTAL");
16042 if (totalMemtrack > 0) {
16043 fullJavaBuilder.append(" (");
16044 fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16045 fullJavaBuilder.append(" memtrack)");
16048 fullJavaBuilder.append("\n");
16050 MemInfoReader memInfo = new MemInfoReader();
16051 memInfo.readMemInfo();
16052 final long[] infos = memInfo.getRawInfo();
16054 StringBuilder memInfoBuilder = new StringBuilder(1024);
16055 Debug.getMemInfo(infos);
16056 memInfoBuilder.append(" MemInfo: ");
16057 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16058 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16059 memInfoBuilder.append(stringifyKBSize(
16060 infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16061 memInfoBuilder.append(stringifyKBSize(
16062 infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16063 memInfoBuilder.append(stringifyKBSize(
16064 infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16065 memInfoBuilder.append(" ");
16066 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16067 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16068 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16069 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16070 if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16071 memInfoBuilder.append(" ZRAM: ");
16072 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16073 memInfoBuilder.append(" RAM, ");
16074 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16075 memInfoBuilder.append(" swap total, ");
16076 memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16077 memInfoBuilder.append(" swap free\n");
16079 final long[] ksm = getKsmInfo();
16080 if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16081 || ksm[KSM_VOLATILE] != 0) {
16082 memInfoBuilder.append(" KSM: ");
16083 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16084 memInfoBuilder.append(" saved from shared ");
16085 memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16086 memInfoBuilder.append("\n ");
16087 memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16088 memInfoBuilder.append(" unshared; ");
16089 memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16090 memInfoBuilder.append(" volatile\n");
16092 memInfoBuilder.append(" Free RAM: ");
16093 memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16094 + memInfo.getFreeSizeKb()));
16095 memInfoBuilder.append("\n");
16096 memInfoBuilder.append(" Used RAM: ");
16097 memInfoBuilder.append(stringifyKBSize(
16098 totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16099 memInfoBuilder.append("\n");
16100 memInfoBuilder.append(" Lost RAM: ");
16101 memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16102 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16103 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16104 memInfoBuilder.append("\n");
16105 Slog.i(TAG, "Low on memory:");
16106 Slog.i(TAG, shortNativeBuilder.toString());
16107 Slog.i(TAG, fullJavaBuilder.toString());
16108 Slog.i(TAG, memInfoBuilder.toString());
16110 StringBuilder dropBuilder = new StringBuilder(1024);
16112 StringWriter oomSw = new StringWriter();
16113 PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16114 StringWriter catSw = new StringWriter();
16115 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16116 String[] emptyArgs = new String[] { };
16117 dumpApplicationMemoryUsage(null, oomPw, " ", emptyArgs, true, catPw);
16119 String oomString = oomSw.toString();
16121 dropBuilder.append("Low on memory:");
16122 dropBuilder.append(stack);
16123 dropBuilder.append('\n');
16124 dropBuilder.append(fullNativeBuilder);
16125 dropBuilder.append(fullJavaBuilder);
16126 dropBuilder.append('\n');
16127 dropBuilder.append(memInfoBuilder);
16128 dropBuilder.append('\n');
16130 dropBuilder.append(oomString);
16131 dropBuilder.append('\n');
16133 StringWriter catSw = new StringWriter();
16134 synchronized (ActivityManagerService.this) {
16135 PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16136 String[] emptyArgs = new String[] { };
16138 dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16140 mServices.dumpServicesLocked(null, catPw, emptyArgs, 0,
16141 false, false, null);
16143 dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16146 dropBuilder.append(catSw.toString());
16147 addErrorToDropBox("lowmem", null, "system_server", null,
16148 null, tag.toString(), dropBuilder.toString(), null, null);
16149 //Slog.i(TAG, "Sent to dropbox:");
16150 //Slog.i(TAG, dropBuilder.toString());
16151 synchronized (ActivityManagerService.this) {
16152 long now = SystemClock.uptimeMillis();
16153 if (mLastMemUsageReportTime < now) {
16154 mLastMemUsageReportTime = now;
16160 * Searches array of arguments for the specified string
16161 * @param args array of argument strings
16162 * @param value value to search for
16163 * @return true if the value is contained in the array
16165 private static boolean scanArgs(String[] args, String value) {
16166 if (args != null) {
16167 for (String arg : args) {
16168 if (value.equals(arg)) {
16176 private final boolean removeDyingProviderLocked(ProcessRecord proc,
16177 ContentProviderRecord cpr, boolean always) {
16178 final boolean inLaunching = mLaunchingProviders.contains(cpr);
16180 if (!inLaunching || always) {
16181 synchronized (cpr) {
16182 cpr.launchingApp = null;
16185 mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16186 String names[] = cpr.info.authority.split(";");
16187 for (int j = 0; j < names.length; j++) {
16188 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16192 for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16193 ContentProviderConnection conn = cpr.connections.get(i);
16194 if (conn.waiting) {
16195 // If this connection is waiting for the provider, then we don't
16196 // need to mess with its process unless we are always removing
16197 // or for some reason the provider is not currently launching.
16198 if (inLaunching && !always) {
16202 ProcessRecord capp = conn.client;
16204 if (conn.stableCount > 0) {
16205 if (!capp.persistent && capp.thread != null
16207 && capp.pid != MY_PID) {
16208 capp.kill("depends on provider "
16209 + cpr.name.flattenToShortString()
16210 + " in dying proc " + (proc != null ? proc.processName : "??"), true);
16212 } else if (capp.thread != null && conn.provider.provider != null) {
16214 capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16215 } catch (RemoteException e) {
16217 // In the protocol here, we don't expect the client to correctly
16218 // clean up this connection, we'll just remove it.
16219 cpr.connections.remove(i);
16220 if (conn.client.conProviders.remove(conn)) {
16221 stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16226 if (inLaunching && always) {
16227 mLaunchingProviders.remove(cpr);
16229 return inLaunching;
16233 * Main code for cleaning up a process when it has gone away. This is
16234 * called both as a result of the process dying, or directly when stopping
16235 * a process when running in single process mode.
16237 * @return Returns true if the given process has been restarted, so the
16238 * app that was passed in must remain on the process lists.
16240 private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16241 boolean restarting, boolean allowRestart, int index) {
16243 removeLruProcessLocked(app);
16244 ProcessList.remove(app.pid);
16247 mProcessesToGc.remove(app);
16248 mPendingPssProcesses.remove(app);
16250 // Dismiss any open dialogs.
16251 if (app.crashDialog != null && !app.forceCrashReport) {
16252 app.crashDialog.dismiss();
16253 app.crashDialog = null;
16255 if (app.anrDialog != null) {
16256 app.anrDialog.dismiss();
16257 app.anrDialog = null;
16259 if (app.waitDialog != null) {
16260 app.waitDialog.dismiss();
16261 app.waitDialog = null;
16264 app.crashing = false;
16265 app.notResponding = false;
16267 app.resetPackageList(mProcessStats);
16268 app.unlinkDeathRecipient();
16269 app.makeInactive(mProcessStats);
16270 app.waitingToKill = null;
16271 app.forcingToForeground = null;
16272 updateProcessForegroundLocked(app, false, false);
16273 app.foregroundActivities = false;
16274 app.hasShownUi = false;
16275 app.treatLikeActivity = false;
16276 app.hasAboveClient = false;
16277 app.hasClientActivities = false;
16279 mServices.killServicesLocked(app, allowRestart);
16281 boolean restart = false;
16283 // Remove published content providers.
16284 for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16285 ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16286 final boolean always = app.bad || !allowRestart;
16287 boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16288 if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16289 // We left the provider in the launching list, need to
16294 cpr.provider = null;
16297 app.pubProviders.clear();
16299 // Take care of any launching providers waiting for this process.
16300 if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16304 // Unregister from connected content providers.
16305 if (!app.conProviders.isEmpty()) {
16306 for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16307 ContentProviderConnection conn = app.conProviders.get(i);
16308 conn.provider.connections.remove(conn);
16309 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16310 conn.provider.name);
16312 app.conProviders.clear();
16315 // At this point there may be remaining entries in mLaunchingProviders
16316 // where we were the only one waiting, so they are no longer of use.
16317 // Look for these and clean up if found.
16318 // XXX Commented out for now. Trying to figure out a way to reproduce
16319 // the actual situation to identify what is actually going on.
16321 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16322 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16323 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16324 synchronized (cpr) {
16325 cpr.launchingApp = null;
16332 skipCurrentReceiverLocked(app);
16334 // Unregister any receivers.
16335 for (int i = app.receivers.size() - 1; i >= 0; i--) {
16336 removeReceiverLocked(app.receivers.valueAt(i));
16338 app.receivers.clear();
16340 // If the app is undergoing backup, tell the backup manager about it
16341 if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16342 if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16343 + mBackupTarget.appInfo + " died during backup");
16345 IBackupManager bm = IBackupManager.Stub.asInterface(
16346 ServiceManager.getService(Context.BACKUP_SERVICE));
16347 bm.agentDisconnected(app.info.packageName);
16348 } catch (RemoteException e) {
16349 // can't happen; backup manager is local
16353 for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16354 ProcessChangeItem item = mPendingProcessChanges.get(i);
16355 if (item.pid == app.pid) {
16356 mPendingProcessChanges.remove(i);
16357 mAvailProcessChanges.add(item);
16360 mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16361 null).sendToTarget();
16363 // If the caller is restarting this app, then leave it in its
16364 // current lists and let the caller take care of it.
16369 if (!app.persistent || app.isolated) {
16370 if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16371 "Removing non-persistent process during cleanup: " + app);
16372 removeProcessNameLocked(app.processName, app.uid);
16373 if (mHeavyWeightProcess == app) {
16374 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16375 mHeavyWeightProcess.userId, 0));
16376 mHeavyWeightProcess = null;
16378 } else if (!app.removed) {
16379 // This app is persistent, so we need to keep its record around.
16380 // If it is not already on the pending app list, add it there
16381 // and start a new process for it.
16382 if (mPersistentStartingProcesses.indexOf(app) < 0) {
16383 mPersistentStartingProcesses.add(app);
16387 if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
16388 TAG_CLEANUP, "Clean-up removing on hold: " + app);
16389 mProcessesOnHold.remove(app);
16391 if (app == mHomeProcess) {
16392 mHomeProcess = null;
16394 if (app == mPreviousProcess) {
16395 mPreviousProcess = null;
16398 if (restart && !app.isolated) {
16399 // We have components that still need to be running in the
16400 // process, so re-launch it.
16402 ProcessList.remove(app.pid);
16404 addProcessNameLocked(app);
16405 startProcessLocked(app, "restart", app.processName);
16407 } else if (app.pid > 0 && app.pid != MY_PID) {
16410 synchronized (mPidsSelfLocked) {
16411 mPidsSelfLocked.remove(app.pid);
16412 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
16414 mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
16415 if (app.isolated) {
16416 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
16423 boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
16424 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16425 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16426 if (cpr.launchingApp == app) {
16433 boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
16434 // Look through the content providers we are waiting to have launched,
16435 // and if any run in this process then either schedule a restart of
16436 // the process or kill the client waiting for it if this process has
16438 boolean restart = false;
16439 for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16440 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16441 if (cpr.launchingApp == app) {
16442 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
16445 removeDyingProviderLocked(app, cpr, true);
16452 // =========================================================
16454 // =========================================================
16457 public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
16459 enforceNotIsolatedCaller("getServices");
16460 synchronized (this) {
16461 return mServices.getRunningServiceInfoLocked(maxNum, flags);
16466 public PendingIntent getRunningServiceControlPanel(ComponentName name) {
16467 enforceNotIsolatedCaller("getRunningServiceControlPanel");
16468 synchronized (this) {
16469 return mServices.getRunningServiceControlPanelLocked(name);
16474 public ComponentName startService(IApplicationThread caller, Intent service,
16475 String resolvedType, String callingPackage, int userId)
16476 throws TransactionTooLargeException {
16477 enforceNotIsolatedCaller("startService");
16478 // Refuse possible leaked file descriptors
16479 if (service != null && service.hasFileDescriptors() == true) {
16480 throw new IllegalArgumentException("File descriptors passed in Intent");
16483 if (callingPackage == null) {
16484 throw new IllegalArgumentException("callingPackage cannot be null");
16487 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16488 "startService: " + service + " type=" + resolvedType);
16489 synchronized(this) {
16490 final int callingPid = Binder.getCallingPid();
16491 final int callingUid = Binder.getCallingUid();
16492 final long origId = Binder.clearCallingIdentity();
16493 ComponentName res = mServices.startServiceLocked(caller, service,
16494 resolvedType, callingPid, callingUid, callingPackage, userId);
16495 Binder.restoreCallingIdentity(origId);
16500 ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
16501 String callingPackage, int userId)
16502 throws TransactionTooLargeException {
16503 synchronized(this) {
16504 if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
16505 "startServiceInPackage: " + service + " type=" + resolvedType);
16506 final long origId = Binder.clearCallingIdentity();
16507 ComponentName res = mServices.startServiceLocked(null, service,
16508 resolvedType, -1, uid, callingPackage, userId);
16509 Binder.restoreCallingIdentity(origId);
16515 public int stopService(IApplicationThread caller, Intent service,
16516 String resolvedType, int userId) {
16517 enforceNotIsolatedCaller("stopService");
16518 // Refuse possible leaked file descriptors
16519 if (service != null && service.hasFileDescriptors() == true) {
16520 throw new IllegalArgumentException("File descriptors passed in Intent");
16523 synchronized(this) {
16524 return mServices.stopServiceLocked(caller, service, resolvedType, userId);
16529 public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
16530 enforceNotIsolatedCaller("peekService");
16531 // Refuse possible leaked file descriptors
16532 if (service != null && service.hasFileDescriptors() == true) {
16533 throw new IllegalArgumentException("File descriptors passed in Intent");
16536 if (callingPackage == null) {
16537 throw new IllegalArgumentException("callingPackage cannot be null");
16540 synchronized(this) {
16541 return mServices.peekServiceLocked(service, resolvedType, callingPackage);
16546 public boolean stopServiceToken(ComponentName className, IBinder token,
16548 synchronized(this) {
16549 return mServices.stopServiceTokenLocked(className, token, startId);
16554 public void setServiceForeground(ComponentName className, IBinder token,
16555 int id, Notification notification, boolean removeNotification) {
16556 synchronized(this) {
16557 mServices.setServiceForegroundLocked(className, token, id, notification,
16558 removeNotification);
16563 public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
16564 boolean requireFull, String name, String callerPackage) {
16565 return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
16566 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
16569 boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
16570 String className, int flags) {
16571 boolean result = false;
16572 // For apps that don't have pre-defined UIDs, check for permission
16573 if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
16574 if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16575 if (ActivityManager.checkUidPermission(
16576 INTERACT_ACROSS_USERS,
16577 aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
16578 ComponentName comp = new ComponentName(aInfo.packageName, className);
16579 String msg = "Permission Denial: Component " + comp.flattenToShortString()
16580 + " requests FLAG_SINGLE_USER, but app does not hold "
16581 + INTERACT_ACROSS_USERS;
16583 throw new SecurityException(msg);
16585 // Permission passed
16588 } else if ("system".equals(componentProcessName)) {
16590 } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
16591 // Phone app and persistent apps are allowed to export singleuser providers.
16592 result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
16593 || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
16595 if (DEBUG_MU) Slog.v(TAG_MU,
16596 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
16597 + Integer.toHexString(flags) + ") = " + result);
16602 * Checks to see if the caller is in the same app as the singleton
16603 * component, or the component is in a special app. It allows special apps
16604 * to export singleton components but prevents exporting singleton
16605 * components for regular apps.
16607 boolean isValidSingletonCall(int callingUid, int componentUid) {
16608 int componentAppId = UserHandle.getAppId(componentUid);
16609 return UserHandle.isSameApp(callingUid, componentUid)
16610 || componentAppId == Process.SYSTEM_UID
16611 || componentAppId == Process.PHONE_UID
16612 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
16613 == PackageManager.PERMISSION_GRANTED;
16616 public int bindService(IApplicationThread caller, IBinder token, Intent service,
16617 String resolvedType, IServiceConnection connection, int flags, String callingPackage,
16618 int userId) throws TransactionTooLargeException {
16619 enforceNotIsolatedCaller("bindService");
16621 // Refuse possible leaked file descriptors
16622 if (service != null && service.hasFileDescriptors() == true) {
16623 throw new IllegalArgumentException("File descriptors passed in Intent");
16626 if (callingPackage == null) {
16627 throw new IllegalArgumentException("callingPackage cannot be null");
16630 synchronized(this) {
16631 return mServices.bindServiceLocked(caller, token, service,
16632 resolvedType, connection, flags, callingPackage, userId);
16636 public boolean unbindService(IServiceConnection connection) {
16637 synchronized (this) {
16638 return mServices.unbindServiceLocked(connection);
16642 public void publishService(IBinder token, Intent intent, IBinder service) {
16643 // Refuse possible leaked file descriptors
16644 if (intent != null && intent.hasFileDescriptors() == true) {
16645 throw new IllegalArgumentException("File descriptors passed in Intent");
16648 synchronized(this) {
16649 if (!(token instanceof ServiceRecord)) {
16650 throw new IllegalArgumentException("Invalid service token");
16652 mServices.publishServiceLocked((ServiceRecord)token, intent, service);
16656 public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
16657 // Refuse possible leaked file descriptors
16658 if (intent != null && intent.hasFileDescriptors() == true) {
16659 throw new IllegalArgumentException("File descriptors passed in Intent");
16662 synchronized(this) {
16663 mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
16667 public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
16668 synchronized(this) {
16669 if (!(token instanceof ServiceRecord)) {
16670 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
16671 throw new IllegalArgumentException("Invalid service token");
16673 mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
16677 // =========================================================
16678 // BACKUP AND RESTORE
16679 // =========================================================
16681 // Cause the target app to be launched if necessary and its backup agent
16682 // instantiated. The backup agent will invoke backupAgentCreated() on the
16683 // activity manager to announce its creation.
16684 public boolean bindBackupAgent(ApplicationInfo app, int backupMode) {
16685 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
16686 "bindBackupAgent: app=" + app + " mode=" + backupMode);
16687 enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
16689 synchronized(this) {
16690 // !!! TODO: currently no check here that we're already bound
16691 BatteryStatsImpl.Uid.Pkg.Serv ss = null;
16692 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
16693 synchronized (stats) {
16694 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
16697 // Backup agent is now in use, its package can't be stopped.
16699 AppGlobals.getPackageManager().setPackageStoppedState(
16700 app.packageName, false, UserHandle.getUserId(app.uid));
16701 } catch (RemoteException e) {
16702 } catch (IllegalArgumentException e) {
16703 Slog.w(TAG, "Failed trying to unstop package "
16704 + app.packageName + ": " + e);
16707 BackupRecord r = new BackupRecord(ss, app, backupMode);
16708 ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
16709 ? new ComponentName(app.packageName, app.backupAgentName)
16710 : new ComponentName("android", "FullBackupAgent");
16711 // startProcessLocked() returns existing proc's record if it's already running
16712 ProcessRecord proc = startProcessLocked(app.processName, app,
16713 false, 0, "backup", hostingName, false, false, false);
16714 if (proc == null) {
16715 Slog.e(TAG, "Unable to start backup agent process " + r);
16721 mBackupAppName = app.packageName;
16723 // Try not to kill the process during backup
16724 updateOomAdjLocked(proc);
16726 // If the process is already attached, schedule the creation of the backup agent now.
16727 // If it is not yet live, this will be done when it attaches to the framework.
16728 if (proc.thread != null) {
16729 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
16731 proc.thread.scheduleCreateBackupAgent(app,
16732 compatibilityInfoForPackageLocked(app), backupMode);
16733 } catch (RemoteException e) {
16734 // Will time out on the backup manager side
16737 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
16739 // Invariants: at this point, the target app process exists and the application
16740 // is either already running or in the process of coming up. mBackupTarget and
16741 // mBackupAppName describe the app, so that when it binds back to the AM we
16742 // know that it's scheduled for a backup-agent operation.
16749 public void clearPendingBackup() {
16750 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
16751 enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
16753 synchronized (this) {
16754 mBackupTarget = null;
16755 mBackupAppName = null;
16759 // A backup agent has just come up
16760 public void backupAgentCreated(String agentPackageName, IBinder agent) {
16761 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
16764 synchronized(this) {
16765 if (!agentPackageName.equals(mBackupAppName)) {
16766 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
16771 long oldIdent = Binder.clearCallingIdentity();
16773 IBackupManager bm = IBackupManager.Stub.asInterface(
16774 ServiceManager.getService(Context.BACKUP_SERVICE));
16775 bm.agentConnected(agentPackageName, agent);
16776 } catch (RemoteException e) {
16777 // can't happen; the backup manager service is local
16778 } catch (Exception e) {
16779 Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
16780 e.printStackTrace();
16782 Binder.restoreCallingIdentity(oldIdent);
16786 // done with this agent
16787 public void unbindBackupAgent(ApplicationInfo appInfo) {
16788 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
16789 if (appInfo == null) {
16790 Slog.w(TAG, "unbind backup agent for null app");
16794 synchronized(this) {
16796 if (mBackupAppName == null) {
16797 Slog.w(TAG, "Unbinding backup agent with no active backup");
16801 if (!mBackupAppName.equals(appInfo.packageName)) {
16802 Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
16806 // Not backing this app up any more; reset its OOM adjustment
16807 final ProcessRecord proc = mBackupTarget.app;
16808 updateOomAdjLocked(proc);
16810 // If the app crashed during backup, 'thread' will be null here
16811 if (proc.thread != null) {
16813 proc.thread.scheduleDestroyBackupAgent(appInfo,
16814 compatibilityInfoForPackageLocked(appInfo));
16815 } catch (Exception e) {
16816 Slog.e(TAG, "Exception when unbinding backup agent:");
16817 e.printStackTrace();
16821 mBackupTarget = null;
16822 mBackupAppName = null;
16826 // =========================================================
16828 // =========================================================
16830 boolean isPendingBroadcastProcessLocked(int pid) {
16831 return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
16832 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
16835 void skipPendingBroadcastLocked(int pid) {
16836 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
16837 for (BroadcastQueue queue : mBroadcastQueues) {
16838 queue.skipPendingBroadcastLocked(pid);
16842 // The app just attached; send any pending broadcasts that it should receive
16843 boolean sendPendingBroadcastsLocked(ProcessRecord app) {
16844 boolean didSomething = false;
16845 for (BroadcastQueue queue : mBroadcastQueues) {
16846 didSomething |= queue.sendPendingBroadcastsLocked(app);
16848 return didSomething;
16851 public Intent registerReceiver(IApplicationThread caller, String callerPackage,
16852 IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
16853 enforceNotIsolatedCaller("registerReceiver");
16854 ArrayList<Intent> stickyIntents = null;
16855 ProcessRecord callerApp = null;
16858 synchronized(this) {
16859 if (caller != null) {
16860 callerApp = getRecordForAppLocked(caller);
16861 if (callerApp == null) {
16862 throw new SecurityException(
16863 "Unable to find app for caller " + caller
16864 + " (pid=" + Binder.getCallingPid()
16865 + ") when registering receiver " + receiver);
16867 if (callerApp.info.uid != Process.SYSTEM_UID &&
16868 !callerApp.pkgList.containsKey(callerPackage) &&
16869 !"android".equals(callerPackage)) {
16870 throw new SecurityException("Given caller package " + callerPackage
16871 + " is not running in process " + callerApp);
16873 callingUid = callerApp.info.uid;
16874 callingPid = callerApp.pid;
16876 callerPackage = null;
16877 callingUid = Binder.getCallingUid();
16878 callingPid = Binder.getCallingPid();
16881 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
16882 ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
16884 Iterator<String> actions = filter.actionsIterator();
16885 if (actions == null) {
16886 ArrayList<String> noAction = new ArrayList<String>(1);
16887 noAction.add(null);
16888 actions = noAction.iterator();
16891 // Collect stickies of users
16892 int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
16893 while (actions.hasNext()) {
16894 String action = actions.next();
16895 for (int id : userIds) {
16896 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
16897 if (stickies != null) {
16898 ArrayList<Intent> intents = stickies.get(action);
16899 if (intents != null) {
16900 if (stickyIntents == null) {
16901 stickyIntents = new ArrayList<Intent>();
16903 stickyIntents.addAll(intents);
16910 ArrayList<Intent> allSticky = null;
16911 if (stickyIntents != null) {
16912 final ContentResolver resolver = mContext.getContentResolver();
16913 // Look for any matching sticky broadcasts...
16914 for (int i = 0, N = stickyIntents.size(); i < N; i++) {
16915 Intent intent = stickyIntents.get(i);
16916 // If intent has scheme "content", it will need to acccess
16917 // provider that needs to lock mProviderMap in ActivityThread
16918 // and also it may need to wait application response, so we
16919 // cannot lock ActivityManagerService here.
16920 if (filter.match(resolver, intent, true, TAG) >= 0) {
16921 if (allSticky == null) {
16922 allSticky = new ArrayList<Intent>();
16924 allSticky.add(intent);
16929 // The first sticky in the list is returned directly back to the client.
16930 Intent sticky = allSticky != null ? allSticky.get(0) : null;
16931 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
16932 if (receiver == null) {
16936 synchronized (this) {
16937 if (callerApp != null && (callerApp.thread == null
16938 || callerApp.thread.asBinder() != caller.asBinder())) {
16939 // Original caller already died
16942 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
16944 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
16946 if (rl.app != null) {
16947 rl.app.receivers.add(rl);
16950 receiver.asBinder().linkToDeath(rl, 0);
16951 } catch (RemoteException e) {
16954 rl.linkedToDeath = true;
16956 mRegisteredReceivers.put(receiver.asBinder(), rl);
16957 } else if (rl.uid != callingUid) {
16958 throw new IllegalArgumentException(
16959 "Receiver requested to register for uid " + callingUid
16960 + " was previously registered for uid " + rl.uid);
16961 } else if (rl.pid != callingPid) {
16962 throw new IllegalArgumentException(
16963 "Receiver requested to register for pid " + callingPid
16964 + " was previously registered for pid " + rl.pid);
16965 } else if (rl.userId != userId) {
16966 throw new IllegalArgumentException(
16967 "Receiver requested to register for user " + userId
16968 + " was previously registered for user " + rl.userId);
16970 BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
16971 permission, callingUid, userId);
16973 if (!bf.debugCheck()) {
16974 Slog.w(TAG, "==> For Dynamic broadcast");
16976 mReceiverResolver.addFilter(bf);
16978 // Enqueue broadcasts for all existing stickies that match
16980 if (allSticky != null) {
16981 ArrayList receivers = new ArrayList();
16984 final int stickyCount = allSticky.size();
16985 for (int i = 0; i < stickyCount; i++) {
16986 Intent intent = allSticky.get(i);
16987 BroadcastQueue queue = broadcastQueueForIntent(intent);
16988 BroadcastRecord r = new BroadcastRecord(queue, intent, null,
16989 null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
16990 null, 0, null, null, false, true, true, -1);
16991 queue.enqueueParallelBroadcastLocked(r);
16992 queue.scheduleBroadcastsLocked();
17000 public void unregisterReceiver(IIntentReceiver receiver) {
17001 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17003 final long origId = Binder.clearCallingIdentity();
17005 boolean doTrim = false;
17007 synchronized(this) {
17008 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17010 final BroadcastRecord r = rl.curBroadcast;
17011 if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17012 final boolean doNext = r.queue.finishReceiverLocked(
17013 r, r.resultCode, r.resultData, r.resultExtras,
17014 r.resultAbort, false);
17017 r.queue.processNextBroadcast(false);
17021 if (rl.app != null) {
17022 rl.app.receivers.remove(rl);
17024 removeReceiverLocked(rl);
17025 if (rl.linkedToDeath) {
17026 rl.linkedToDeath = false;
17027 rl.receiver.asBinder().unlinkToDeath(rl, 0);
17032 // If we actually concluded any broadcasts, we might now be able
17033 // to trim the recipients' apps from our working set
17035 trimApplications();
17040 Binder.restoreCallingIdentity(origId);
17044 void removeReceiverLocked(ReceiverList rl) {
17045 mRegisteredReceivers.remove(rl.receiver.asBinder());
17046 for (int i = rl.size() - 1; i >= 0; i--) {
17047 mReceiverResolver.removeFilter(rl.get(i));
17051 private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17052 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17053 ProcessRecord r = mLruProcesses.get(i);
17054 if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17056 r.thread.dispatchPackageBroadcast(cmd, packages);
17057 } catch (RemoteException ex) {
17063 private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17064 int callingUid, int[] users) {
17065 // TODO: come back and remove this assumption to triage all broadcasts
17066 int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17068 List<ResolveInfo> receivers = null;
17070 HashSet<ComponentName> singleUserReceivers = null;
17071 boolean scannedFirstReceivers = false;
17072 for (int user : users) {
17073 // Skip users that have Shell restrictions, with exception of always permitted
17074 // Shell broadcasts
17075 if (callingUid == Process.SHELL_UID
17076 && mUserController.hasUserRestriction(
17077 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17078 && !isPermittedShellBroadcast(intent)) {
17081 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17082 .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17083 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17084 // If this is not the system user, we need to check for
17085 // any receivers that should be filtered out.
17086 for (int i=0; i<newReceivers.size(); i++) {
17087 ResolveInfo ri = newReceivers.get(i);
17088 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17089 newReceivers.remove(i);
17094 if (newReceivers != null && newReceivers.size() == 0) {
17095 newReceivers = null;
17097 if (receivers == null) {
17098 receivers = newReceivers;
17099 } else if (newReceivers != null) {
17100 // We need to concatenate the additional receivers
17101 // found with what we have do far. This would be easy,
17102 // but we also need to de-dup any receivers that are
17104 if (!scannedFirstReceivers) {
17105 // Collect any single user receivers we had already retrieved.
17106 scannedFirstReceivers = true;
17107 for (int i=0; i<receivers.size(); i++) {
17108 ResolveInfo ri = receivers.get(i);
17109 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17110 ComponentName cn = new ComponentName(
17111 ri.activityInfo.packageName, ri.activityInfo.name);
17112 if (singleUserReceivers == null) {
17113 singleUserReceivers = new HashSet<ComponentName>();
17115 singleUserReceivers.add(cn);
17119 // Add the new results to the existing results, tracking
17120 // and de-dupping single user receivers.
17121 for (int i=0; i<newReceivers.size(); i++) {
17122 ResolveInfo ri = newReceivers.get(i);
17123 if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17124 ComponentName cn = new ComponentName(
17125 ri.activityInfo.packageName, ri.activityInfo.name);
17126 if (singleUserReceivers == null) {
17127 singleUserReceivers = new HashSet<ComponentName>();
17129 if (!singleUserReceivers.contains(cn)) {
17130 singleUserReceivers.add(cn);
17139 } catch (RemoteException ex) {
17140 // pm is in same process, this will never happen.
17145 private boolean isPermittedShellBroadcast(Intent intent) {
17146 // remote bugreport should always be allowed to be taken
17147 return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17150 final int broadcastIntentLocked(ProcessRecord callerApp,
17151 String callerPackage, Intent intent, String resolvedType,
17152 IIntentReceiver resultTo, int resultCode, String resultData,
17153 Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17154 boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17155 intent = new Intent(intent);
17157 // By default broadcasts do not go to stopped apps.
17158 intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17160 // If we have not finished booting, don't allow this to launch new processes.
17161 if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17162 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17165 if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17166 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17167 + " ordered=" + ordered + " userid=" + userId);
17168 if ((resultTo != null) && !ordered) {
17169 Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17172 userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17173 ALLOW_NON_FULL, "broadcast", callerPackage);
17175 // Make sure that the user who is receiving this broadcast is running.
17176 // If not, we will just skip it. Make an exception for shutdown broadcasts
17177 // and upgrade steps.
17179 if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17180 if ((callingUid != Process.SYSTEM_UID
17181 || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17182 && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17183 Slog.w(TAG, "Skipping broadcast of " + intent
17184 + ": user " + userId + " is stopped");
17185 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17189 BroadcastOptions brOptions = null;
17190 if (bOptions != null) {
17191 brOptions = new BroadcastOptions(bOptions);
17192 if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17193 // See if the caller is allowed to do this. Note we are checking against
17194 // the actual real caller (not whoever provided the operation as say a
17195 // PendingIntent), because that who is actually supplied the arguments.
17196 if (checkComponentPermission(
17197 android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17198 Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17199 != PackageManager.PERMISSION_GRANTED) {
17200 String msg = "Permission Denial: " + intent.getAction()
17201 + " broadcast from " + callerPackage + " (pid=" + callingPid
17202 + ", uid=" + callingUid + ")"
17204 + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17206 throw new SecurityException(msg);
17211 // Verify that protected broadcasts are only being sent by system code,
17212 // and that system code is only sending protected broadcasts.
17213 final String action = intent.getAction();
17214 final boolean isProtectedBroadcast;
17216 isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17217 } catch (RemoteException e) {
17218 Slog.w(TAG, "Remote exception", e);
17219 return ActivityManager.BROADCAST_SUCCESS;
17222 final boolean isCallerSystem;
17223 switch (UserHandle.getAppId(callingUid)) {
17224 case Process.ROOT_UID:
17225 case Process.SYSTEM_UID:
17226 case Process.PHONE_UID:
17227 case Process.BLUETOOTH_UID:
17228 case Process.NFC_UID:
17229 isCallerSystem = true;
17232 isCallerSystem = (callerApp != null) && callerApp.persistent;
17236 if (isCallerSystem) {
17237 if (isProtectedBroadcast
17238 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17239 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17240 || Intent.ACTION_GET_PERMISSIONS_COUNT.equals(action)
17241 || Intent.ACTION_GET_PERMISSIONS_PACKAGES.equals(action)
17242 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17243 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17244 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)) {
17245 // Broadcast is either protected, or it's a public action that
17246 // we've relaxed, so it's fine for system internals to send.
17248 // The vast majority of broadcasts sent from system internals
17249 // should be protected to avoid security holes, so yell loudly
17250 // to ensure we examine these cases.
17251 Log.wtf(TAG, "Sending non-protected broadcast " + action
17252 + " from system", new Throwable());
17256 if (isProtectedBroadcast) {
17257 String msg = "Permission Denial: not allowed to send broadcast "
17258 + action + " from pid="
17259 + callingPid + ", uid=" + callingUid;
17261 throw new SecurityException(msg);
17263 } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17264 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17265 // Special case for compatibility: we don't want apps to send this,
17266 // but historically it has not been protected and apps may be using it
17267 // to poke their own app widget. So, instead of making it protected,
17268 // just limit it to the caller.
17269 if (callerApp == null) {
17270 String msg = "Permission Denial: not allowed to send broadcast "
17271 + action + " from unknown caller.";
17273 throw new SecurityException(msg);
17274 } else if (intent.getComponent() != null) {
17275 // They are good enough to send to an explicit component... verify
17276 // it is being sent to the calling app.
17277 if (!intent.getComponent().getPackageName().equals(
17278 callerApp.info.packageName)) {
17279 String msg = "Permission Denial: not allowed to send broadcast "
17281 + intent.getComponent().getPackageName() + " from "
17282 + callerApp.info.packageName;
17284 throw new SecurityException(msg);
17287 // Limit broadcast to their own package.
17288 intent.setPackage(callerApp.info.packageName);
17293 if (action != null) {
17295 case Intent.ACTION_UID_REMOVED:
17296 case Intent.ACTION_PACKAGE_REMOVED:
17297 case Intent.ACTION_PACKAGE_CHANGED:
17298 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17299 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17300 case Intent.ACTION_PACKAGES_SUSPENDED:
17301 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17302 // Handle special intents: if this broadcast is from the package
17303 // manager about a package being removed, we need to remove all of
17304 // its activities from the history stack.
17305 if (checkComponentPermission(
17306 android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17307 callingPid, callingUid, -1, true)
17308 != PackageManager.PERMISSION_GRANTED) {
17309 String msg = "Permission Denial: " + intent.getAction()
17310 + " broadcast from " + callerPackage + " (pid=" + callingPid
17311 + ", uid=" + callingUid + ")"
17313 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17315 throw new SecurityException(msg);
17318 case Intent.ACTION_UID_REMOVED:
17319 final Bundle intentExtras = intent.getExtras();
17320 final int uid = intentExtras != null
17321 ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
17323 mBatteryStatsService.removeUid(uid);
17324 mAppOpsService.uidRemoved(uid);
17327 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17328 // If resources are unavailable just force stop all those packages
17329 // and flush the attribute cache as well.
17331 intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17332 if (list != null && list.length > 0) {
17333 for (int i = 0; i < list.length; i++) {
17334 forceStopPackageLocked(list[i], -1, false, true, true,
17335 false, false, userId, "storage unmount");
17337 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17338 sendPackageBroadcastLocked(
17339 IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
17343 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17344 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
17346 case Intent.ACTION_PACKAGE_REMOVED:
17347 case Intent.ACTION_PACKAGE_CHANGED:
17348 Uri data = intent.getData();
17350 if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
17351 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
17352 final boolean replacing =
17353 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17354 final boolean killProcess =
17355 !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
17356 final boolean fullUninstall = removed && !replacing;
17358 forceStopPackageLocked(ssp, UserHandle.getAppId(
17359 intent.getIntExtra(Intent.EXTRA_UID, -1)),
17360 false, true, true, false, fullUninstall, userId,
17361 removed ? "pkg removed" : "pkg changed");
17364 final int cmd = killProcess
17365 ? IApplicationThread.PACKAGE_REMOVED
17366 : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
17367 sendPackageBroadcastLocked(cmd,
17368 new String[] {ssp}, userId);
17369 if (fullUninstall) {
17370 mAppOpsService.packageRemoved(
17371 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
17373 // Remove all permissions granted from/to this package
17374 removeUriPermissionsForPackageLocked(ssp, userId, true);
17376 removeTasksByPackageNameLocked(ssp, userId);
17377 mBatteryStatsService.notePackageUninstalled(ssp);
17380 cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
17381 intent.getStringArrayExtra(
17382 Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
17386 case Intent.ACTION_PACKAGES_SUSPENDED:
17387 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17388 final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
17389 intent.getAction());
17390 final String[] packageNames = intent.getStringArrayExtra(
17391 Intent.EXTRA_CHANGED_PACKAGE_LIST);
17392 final int userHandle = intent.getIntExtra(
17393 Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
17395 synchronized(ActivityManagerService.this) {
17396 mRecentTasks.onPackagesSuspendedChanged(
17397 packageNames, suspended, userHandle);
17402 case Intent.ACTION_PACKAGE_REPLACED:
17404 final Uri data = intent.getData();
17406 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17407 final ApplicationInfo aInfo =
17408 getPackageManagerInternalLocked().getApplicationInfo(
17411 mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
17412 sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
17413 new String[] {ssp}, userId);
17417 case Intent.ACTION_PACKAGE_ADDED:
17419 // Special case for adding a package: by default turn on compatibility mode.
17420 Uri data = intent.getData();
17422 if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
17423 final boolean replacing =
17424 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
17425 mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
17428 ApplicationInfo ai = AppGlobals.getPackageManager().
17429 getApplicationInfo(ssp, 0, 0);
17430 mBatteryStatsService.notePackageInstalled(ssp,
17431 ai != null ? ai.versionCode : 0);
17432 } catch (RemoteException e) {
17437 case Intent.ACTION_TIMEZONE_CHANGED:
17438 // If this is the time zone changed action, queue up a message that will reset
17439 // the timezone of all currently running processes. This message will get
17440 // queued up before the broadcast happens.
17441 mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
17443 case Intent.ACTION_TIME_CHANGED:
17444 // If the user set the time, let all running processes know.
17445 final int is24Hour =
17446 intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
17448 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
17449 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17450 synchronized (stats) {
17451 stats.noteCurrentTimeChangedLocked();
17454 case Intent.ACTION_CLEAR_DNS_CACHE:
17455 mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
17457 case Proxy.PROXY_CHANGE_ACTION:
17458 ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
17459 mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
17461 case android.hardware.Camera.ACTION_NEW_PICTURE:
17462 case android.hardware.Camera.ACTION_NEW_VIDEO:
17463 // These broadcasts are no longer allowed by the system, since they can
17464 // cause significant thrashing at a crictical point (using the camera).
17465 // Apps should use JobScehduler to monitor for media provider changes.
17466 Slog.w(TAG, action + " no longer allowed; dropping from "
17467 + UserHandle.formatUid(callingUid));
17468 // Lie; we don't want to crash the app.
17469 return ActivityManager.BROADCAST_SUCCESS;
17473 // Add to the sticky list if requested.
17475 if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
17476 callingPid, callingUid)
17477 != PackageManager.PERMISSION_GRANTED) {
17478 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
17479 + callingPid + ", uid=" + callingUid
17480 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17482 throw new SecurityException(msg);
17484 if (requiredPermissions != null && requiredPermissions.length > 0) {
17485 Slog.w(TAG, "Can't broadcast sticky intent " + intent
17486 + " and enforce permissions " + Arrays.toString(requiredPermissions));
17487 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
17489 if (intent.getComponent() != null) {
17490 throw new SecurityException(
17491 "Sticky broadcasts can't target a specific component");
17493 // We use userId directly here, since the "all" target is maintained
17494 // as a separate set of sticky broadcasts.
17495 if (userId != UserHandle.USER_ALL) {
17496 // But first, if this is not a broadcast to all users, then
17497 // make sure it doesn't conflict with an existing broadcast to
17499 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
17500 UserHandle.USER_ALL);
17501 if (stickies != null) {
17502 ArrayList<Intent> list = stickies.get(intent.getAction());
17503 if (list != null) {
17504 int N = list.size();
17506 for (i=0; i<N; i++) {
17507 if (intent.filterEquals(list.get(i))) {
17508 throw new IllegalArgumentException(
17509 "Sticky broadcast " + intent + " for user "
17510 + userId + " conflicts with existing global broadcast");
17516 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17517 if (stickies == null) {
17518 stickies = new ArrayMap<>();
17519 mStickyBroadcasts.put(userId, stickies);
17521 ArrayList<Intent> list = stickies.get(intent.getAction());
17522 if (list == null) {
17523 list = new ArrayList<>();
17524 stickies.put(intent.getAction(), list);
17526 final int stickiesCount = list.size();
17528 for (i = 0; i < stickiesCount; i++) {
17529 if (intent.filterEquals(list.get(i))) {
17530 // This sticky already exists, replace it.
17531 list.set(i, new Intent(intent));
17535 if (i >= stickiesCount) {
17536 list.add(new Intent(intent));
17541 if (userId == UserHandle.USER_ALL) {
17542 // Caller wants broadcast to go to all started users.
17543 users = mUserController.getStartedUserArrayLocked();
17545 // Caller wants broadcast to go to one specific user.
17546 users = new int[] {userId};
17549 // Figure out who all will receive this broadcast.
17550 List receivers = null;
17551 List<BroadcastFilter> registeredReceivers = null;
17552 // Need to resolve the intent to interested receivers...
17553 if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
17555 receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
17557 if (intent.getComponent() == null) {
17558 if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
17559 // Query one target user at a time, excluding shell-restricted users
17560 for (int i = 0; i < users.length; i++) {
17561 if (mUserController.hasUserRestriction(
17562 UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
17565 List<BroadcastFilter> registeredReceiversForUser =
17566 mReceiverResolver.queryIntent(intent,
17567 resolvedType, false, users[i]);
17568 if (registeredReceivers == null) {
17569 registeredReceivers = registeredReceiversForUser;
17570 } else if (registeredReceiversForUser != null) {
17571 registeredReceivers.addAll(registeredReceiversForUser);
17575 registeredReceivers = mReceiverResolver.queryIntent(intent,
17576 resolvedType, false, userId);
17580 final boolean replacePending =
17581 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
17583 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
17584 + " replacePending=" + replacePending);
17586 int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
17587 if (!ordered && NR > 0) {
17588 // If we are not serializing this broadcast, then send the
17589 // registered receivers separately so they don't wait for the
17590 // components to be launched.
17591 final BroadcastQueue queue = broadcastQueueForIntent(intent);
17592 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17593 callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
17594 appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
17595 resultExtras, ordered, sticky, false, userId);
17596 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
17597 final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
17599 queue.enqueueParallelBroadcastLocked(r);
17600 queue.scheduleBroadcastsLocked();
17602 registeredReceivers = null;
17606 // Merge into one list.
17608 if (receivers != null) {
17609 // A special case for PACKAGE_ADDED: do not allow the package
17610 // being added to see this broadcast. This prevents them from
17611 // using this as a back door to get run as soon as they are
17612 // installed. Maybe in the future we want to have a special install
17613 // broadcast or such for apps, but we'd like to deliberately make
17615 String skipPackages[] = null;
17616 if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
17617 || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
17618 || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
17619 Uri data = intent.getData();
17620 if (data != null) {
17621 String pkgName = data.getSchemeSpecificPart();
17622 if (pkgName != null) {
17623 skipPackages = new String[] { pkgName };
17626 } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
17627 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
17629 if (skipPackages != null && (skipPackages.length > 0)) {
17630 for (String skipPackage : skipPackages) {
17631 if (skipPackage != null) {
17632 int NT = receivers.size();
17633 for (int it=0; it<NT; it++) {
17634 ResolveInfo curt = (ResolveInfo)receivers.get(it);
17635 if (curt.activityInfo.packageName.equals(skipPackage)) {
17636 receivers.remove(it);
17645 int NT = receivers != null ? receivers.size() : 0;
17647 ResolveInfo curt = null;
17648 BroadcastFilter curr = null;
17649 while (it < NT && ir < NR) {
17650 if (curt == null) {
17651 curt = (ResolveInfo)receivers.get(it);
17653 if (curr == null) {
17654 curr = registeredReceivers.get(ir);
17656 if (curr.getPriority() >= curt.priority) {
17657 // Insert this broadcast record into the final list.
17658 receivers.add(it, curr);
17664 // Skip to the next ResolveInfo in the final list.
17671 if (receivers == null) {
17672 receivers = new ArrayList();
17674 receivers.add(registeredReceivers.get(ir));
17678 if ((receivers != null && receivers.size() > 0)
17679 || resultTo != null) {
17680 BroadcastQueue queue = broadcastQueueForIntent(intent);
17681 BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
17682 callerPackage, callingPid, callingUid, resolvedType,
17683 requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
17684 resultData, resultExtras, ordered, sticky, false, userId);
17686 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
17687 + ": prev had " + queue.mOrderedBroadcasts.size());
17688 if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
17689 "Enqueueing broadcast " + r.intent.getAction());
17691 boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
17693 queue.enqueueOrderedBroadcastLocked(r);
17694 queue.scheduleBroadcastsLocked();
17698 return ActivityManager.BROADCAST_SUCCESS;
17701 final Intent verifyBroadcastLocked(Intent intent) {
17702 // Refuse possible leaked file descriptors
17703 if (intent != null && intent.hasFileDescriptors() == true) {
17704 throw new IllegalArgumentException("File descriptors passed in Intent");
17707 int flags = intent.getFlags();
17709 if (!mProcessesReady) {
17710 // if the caller really truly claims to know what they're doing, go
17711 // ahead and allow the broadcast without launching any receivers
17712 if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
17713 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
17714 } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
17715 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
17716 + " before boot completion");
17717 throw new IllegalStateException("Cannot broadcast before boot completed");
17721 if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
17722 throw new IllegalArgumentException(
17723 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
17729 public final int broadcastIntent(IApplicationThread caller,
17730 Intent intent, String resolvedType, IIntentReceiver resultTo,
17731 int resultCode, String resultData, Bundle resultExtras,
17732 String[] requiredPermissions, int appOp, Bundle bOptions,
17733 boolean serialized, boolean sticky, int userId) {
17734 enforceNotIsolatedCaller("broadcastIntent");
17735 synchronized(this) {
17736 intent = verifyBroadcastLocked(intent);
17738 final ProcessRecord callerApp = getRecordForAppLocked(caller);
17739 final int callingPid = Binder.getCallingPid();
17740 final int callingUid = Binder.getCallingUid();
17741 final long origId = Binder.clearCallingIdentity();
17742 int res = broadcastIntentLocked(callerApp,
17743 callerApp != null ? callerApp.info.packageName : null,
17744 intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
17745 requiredPermissions, appOp, null, serialized, sticky,
17746 callingPid, callingUid, userId);
17747 Binder.restoreCallingIdentity(origId);
17753 int broadcastIntentInPackage(String packageName, int uid,
17754 Intent intent, String resolvedType, IIntentReceiver resultTo,
17755 int resultCode, String resultData, Bundle resultExtras,
17756 String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
17758 synchronized(this) {
17759 intent = verifyBroadcastLocked(intent);
17761 final long origId = Binder.clearCallingIdentity();
17762 String[] requiredPermissions = requiredPermission == null ? null
17763 : new String[] {requiredPermission};
17764 int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
17765 resultTo, resultCode, resultData, resultExtras,
17766 requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
17767 sticky, -1, uid, userId);
17768 Binder.restoreCallingIdentity(origId);
17773 public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
17774 // Refuse possible leaked file descriptors
17775 if (intent != null && intent.hasFileDescriptors() == true) {
17776 throw new IllegalArgumentException("File descriptors passed in Intent");
17779 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17780 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
17782 synchronized(this) {
17783 if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
17784 != PackageManager.PERMISSION_GRANTED) {
17785 String msg = "Permission Denial: unbroadcastIntent() from pid="
17786 + Binder.getCallingPid()
17787 + ", uid=" + Binder.getCallingUid()
17788 + " requires " + android.Manifest.permission.BROADCAST_STICKY;
17790 throw new SecurityException(msg);
17792 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
17793 if (stickies != null) {
17794 ArrayList<Intent> list = stickies.get(intent.getAction());
17795 if (list != null) {
17796 int N = list.size();
17798 for (i=0; i<N; i++) {
17799 if (intent.filterEquals(list.get(i))) {
17804 if (list.size() <= 0) {
17805 stickies.remove(intent.getAction());
17808 if (stickies.size() <= 0) {
17809 mStickyBroadcasts.remove(userId);
17815 void backgroundServicesFinishedLocked(int userId) {
17816 for (BroadcastQueue queue : mBroadcastQueues) {
17817 queue.backgroundServicesFinishedLocked(userId);
17821 public void finishReceiver(IBinder who, int resultCode, String resultData,
17822 Bundle resultExtras, boolean resultAbort, int flags) {
17823 if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
17825 // Refuse possible leaked file descriptors
17826 if (resultExtras != null && resultExtras.hasFileDescriptors()) {
17827 throw new IllegalArgumentException("File descriptors passed in Bundle");
17830 final long origId = Binder.clearCallingIdentity();
17832 boolean doNext = false;
17835 synchronized(this) {
17836 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
17837 ? mFgBroadcastQueue : mBgBroadcastQueue;
17838 r = queue.getMatchingOrderedReceiver(who);
17840 doNext = r.queue.finishReceiverLocked(r, resultCode,
17841 resultData, resultExtras, resultAbort, true);
17846 r.queue.processNextBroadcast(false);
17848 trimApplications();
17850 Binder.restoreCallingIdentity(origId);
17854 // =========================================================
17856 // =========================================================
17858 public boolean startInstrumentation(ComponentName className,
17859 String profileFile, int flags, Bundle arguments,
17860 IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
17861 int userId, String abiOverride) {
17862 enforceNotIsolatedCaller("startInstrumentation");
17863 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
17864 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
17865 // Refuse possible leaked file descriptors
17866 if (arguments != null && arguments.hasFileDescriptors()) {
17867 throw new IllegalArgumentException("File descriptors passed in Bundle");
17870 synchronized(this) {
17871 InstrumentationInfo ii = null;
17872 ApplicationInfo ai = null;
17874 ii = mContext.getPackageManager().getInstrumentationInfo(
17875 className, STOCK_PM_FLAGS);
17876 ai = AppGlobals.getPackageManager().getApplicationInfo(
17877 ii.targetPackage, STOCK_PM_FLAGS, userId);
17878 } catch (PackageManager.NameNotFoundException e) {
17879 } catch (RemoteException e) {
17882 reportStartInstrumentationFailureLocked(watcher, className,
17883 "Unable to find instrumentation info for: " + className);
17887 reportStartInstrumentationFailureLocked(watcher, className,
17888 "Unable to find instrumentation target package: " + ii.targetPackage);
17891 if (!ai.hasCode()) {
17892 reportStartInstrumentationFailureLocked(watcher, className,
17893 "Instrumentation target has no code: " + ii.targetPackage);
17897 int match = mContext.getPackageManager().checkSignatures(
17898 ii.targetPackage, ii.packageName);
17899 if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
17900 String msg = "Permission Denial: starting instrumentation "
17901 + className + " from pid="
17902 + Binder.getCallingPid()
17903 + ", uid=" + Binder.getCallingPid()
17904 + " not allowed because package " + ii.packageName
17905 + " does not have a signature matching the target "
17906 + ii.targetPackage;
17907 reportStartInstrumentationFailureLocked(watcher, className, msg);
17908 throw new SecurityException(msg);
17911 final long origId = Binder.clearCallingIdentity();
17912 // Instrumentation can kill and relaunch even persistent processes
17913 forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
17915 ProcessRecord app = addAppLocked(ai, false, abiOverride);
17916 app.instrumentationClass = className;
17917 app.instrumentationInfo = ai;
17918 app.instrumentationProfileFile = profileFile;
17919 app.instrumentationArguments = arguments;
17920 app.instrumentationWatcher = watcher;
17921 app.instrumentationUiAutomationConnection = uiAutomationConnection;
17922 app.instrumentationResultClass = className;
17923 Binder.restoreCallingIdentity(origId);
17930 * Report errors that occur while attempting to start Instrumentation. Always writes the
17931 * error to the logs, but if somebody is watching, send the report there too. This enables
17932 * the "am" command to report errors with more information.
17934 * @param watcher The IInstrumentationWatcher. Null if there isn't one.
17935 * @param cn The component name of the instrumentation.
17936 * @param report The error report.
17938 private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
17939 ComponentName cn, String report) {
17940 Slog.w(TAG, report);
17941 if (watcher != null) {
17942 Bundle results = new Bundle();
17943 results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
17944 results.putString("Error", report);
17945 mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
17949 void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
17950 if (app.instrumentationWatcher != null) {
17951 mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
17952 app.instrumentationClass, resultCode, results);
17955 // Can't call out of the system process with a lock held, so post a message.
17956 if (app.instrumentationUiAutomationConnection != null) {
17957 mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
17958 app.instrumentationUiAutomationConnection).sendToTarget();
17961 app.instrumentationWatcher = null;
17962 app.instrumentationUiAutomationConnection = null;
17963 app.instrumentationClass = null;
17964 app.instrumentationInfo = null;
17965 app.instrumentationProfileFile = null;
17966 app.instrumentationArguments = null;
17968 forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
17972 public void finishInstrumentation(IApplicationThread target,
17973 int resultCode, Bundle results) {
17974 int userId = UserHandle.getCallingUserId();
17975 // Refuse possible leaked file descriptors
17976 if (results != null && results.hasFileDescriptors()) {
17977 throw new IllegalArgumentException("File descriptors passed in Intent");
17980 synchronized(this) {
17981 ProcessRecord app = getRecordForAppLocked(target);
17983 Slog.w(TAG, "finishInstrumentation: no app for " + target);
17986 final long origId = Binder.clearCallingIdentity();
17987 finishInstrumentationLocked(app, resultCode, results);
17988 Binder.restoreCallingIdentity(origId);
17992 // =========================================================
17994 // =========================================================
17996 public ConfigurationInfo getDeviceConfigurationInfo() {
17997 ConfigurationInfo config = new ConfigurationInfo();
17998 synchronized (this) {
17999 config.reqTouchScreen = mConfiguration.touchscreen;
18000 config.reqKeyboardType = mConfiguration.keyboard;
18001 config.reqNavigation = mConfiguration.navigation;
18002 if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18003 || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18004 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18006 if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18007 && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18008 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18010 config.reqGlEsVersion = GL_ES_VERSION;
18015 ActivityStack getFocusedStack() {
18016 return mStackSupervisor.getFocusedStack();
18020 public int getFocusedStackId() throws RemoteException {
18021 ActivityStack focusedStack = getFocusedStack();
18022 if (focusedStack != null) {
18023 return focusedStack.getStackId();
18028 public Configuration getConfiguration() {
18030 synchronized(this) {
18031 ci = new Configuration(mConfiguration);
18032 ci.userSetLocale = false;
18038 public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18039 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18040 synchronized (this) {
18041 mSuppressResizeConfigChanges = suppress;
18046 public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18047 enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18048 if (fromStackId == HOME_STACK_ID) {
18049 throw new IllegalArgumentException("You can't move tasks from the home stack.");
18051 synchronized (this) {
18052 final long origId = Binder.clearCallingIdentity();
18053 final ActivityStack stack = mStackSupervisor.getStack(fromStackId);
18054 if (stack != null) {
18055 mWindowManager.deferSurfaceLayout();
18057 if (fromStackId == DOCKED_STACK_ID) {
18059 // We are moving all tasks from the docked stack to the fullscreen stack,
18060 // which is dismissing the docked stack, so resize all other stacks to
18061 // fullscreen here already so we don't end up with resize trashing.
18062 for (int i = FIRST_STATIC_STACK_ID; i <= LAST_STATIC_STACK_ID; i++) {
18063 if (StackId.isResizeableByDockedStack(i)) {
18064 ActivityStack otherStack = mStackSupervisor.getStack(i);
18065 if (otherStack != null) {
18066 mStackSupervisor.resizeStackLocked(i,
18067 null, null, null, PRESERVE_WINDOWS,
18068 true /* allowResizeInDockedMode */);
18073 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
18074 final int size = tasks.size();
18076 for (int i = 0; i < size; i++) {
18077 mStackSupervisor.moveTaskToStackLocked(tasks.get(i).taskId,
18078 FULLSCREEN_WORKSPACE_STACK_ID, onTop, !FORCE_FOCUS,
18079 "moveTasksToFullscreenStack", ANIMATE);
18082 for (int i = size - 1; i >= 0; i--) {
18083 mStackSupervisor.positionTaskInStackLocked(tasks.get(i).taskId,
18084 FULLSCREEN_WORKSPACE_STACK_ID, 0);
18088 mWindowManager.continueSurfaceLayout();
18092 Binder.restoreCallingIdentity(origId);
18097 public void updatePersistentConfiguration(Configuration values) {
18098 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18099 "updateConfiguration()");
18100 enforceWriteSettingsPermission("updateConfiguration()");
18101 if (values == null) {
18102 throw new NullPointerException("Configuration must not be null");
18105 int userId = UserHandle.getCallingUserId();
18107 synchronized(this) {
18108 final long origId = Binder.clearCallingIdentity();
18109 updateConfigurationLocked(values, null, false, true, userId);
18110 Binder.restoreCallingIdentity(origId);
18114 private void updateFontScaleIfNeeded() {
18115 final int currentUserId;
18116 synchronized(this) {
18117 currentUserId = mUserController.getCurrentUserIdLocked();
18119 final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18120 FONT_SCALE, 1.0f, currentUserId);
18121 if (mConfiguration.fontScale != scaleFactor) {
18122 final Configuration configuration = mWindowManager.computeNewConfiguration();
18123 configuration.fontScale = scaleFactor;
18124 updatePersistentConfiguration(configuration);
18128 private void enforceWriteSettingsPermission(String func) {
18129 int uid = Binder.getCallingUid();
18130 if (uid == Process.ROOT_UID) {
18134 if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18135 Settings.getPackageNameForUid(mContext, uid), false)) {
18139 String msg = "Permission Denial: " + func + " from pid="
18140 + Binder.getCallingPid()
18142 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18144 throw new SecurityException(msg);
18147 public void updateConfiguration(Configuration values) {
18148 enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18149 "updateConfiguration()");
18151 synchronized(this) {
18152 if (values == null && mWindowManager != null) {
18153 // sentinel: fetch the current configuration from the window manager
18154 values = mWindowManager.computeNewConfiguration();
18157 if (mWindowManager != null) {
18158 mProcessList.applyDisplaySize(mWindowManager);
18161 final long origId = Binder.clearCallingIdentity();
18162 if (values != null) {
18163 Settings.System.clearConfiguration(values);
18165 updateConfigurationLocked(values, null, false);
18166 Binder.restoreCallingIdentity(origId);
18170 void updateUserConfigurationLocked() {
18171 Configuration configuration = new Configuration(mConfiguration);
18172 Settings.System.getConfigurationForUser(mContext.getContentResolver(), configuration,
18173 mUserController.getCurrentUserIdLocked());
18174 updateConfigurationLocked(configuration, null, false);
18177 boolean updateConfigurationLocked(Configuration values,
18178 ActivityRecord starting, boolean initLocale) {
18179 // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18180 return updateConfigurationLocked(values, starting, initLocale, false,
18181 UserHandle.USER_NULL);
18184 // To cache the list of supported system locales
18185 private String[] mSupportedSystemLocales = null;
18188 * Do either or both things: (1) change the current configuration, and (2)
18189 * make sure the given activity is running with the (now) current
18190 * configuration. Returns true if the activity has been left running, or
18191 * false if <var>starting</var> is being destroyed to match the new
18194 * @param userId is only used when persistent parameter is set to true to persist configuration
18195 * for that particular user
18197 private boolean updateConfigurationLocked(Configuration values,
18198 ActivityRecord starting, boolean initLocale, boolean persistent, int userId) {
18201 if (values != null) {
18202 Configuration newConfig = new Configuration(mConfiguration);
18203 changes = newConfig.updateFrom(values);
18204 if (changes != 0) {
18205 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18206 "Updating configuration to: " + values);
18208 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18210 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18211 final Locale locale;
18212 if (values.getLocales().size() == 1) {
18213 // This is an optimization to avoid the JNI call when the result of
18214 // getFirstMatch() does not depend on the supported locales.
18215 locale = values.getLocales().get(0);
18217 if (mSupportedSystemLocales == null) {
18218 mSupportedSystemLocales =
18219 Resources.getSystem().getAssets().getLocales();
18221 locale = values.getLocales().getFirstMatch(mSupportedSystemLocales);
18223 SystemProperties.set("persist.sys.locale", locale.toLanguageTag());
18224 mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18228 mConfigurationSeq++;
18229 if (mConfigurationSeq <= 0) {
18230 mConfigurationSeq = 1;
18232 newConfig.seq = mConfigurationSeq;
18233 mConfiguration = newConfig;
18234 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18235 mUsageStatsService.reportConfigurationChange(newConfig,
18236 mUserController.getCurrentUserIdLocked());
18237 //mUsageStatsService.noteStartConfig(newConfig);
18239 final Configuration configCopy = new Configuration(mConfiguration);
18241 // TODO: If our config changes, should we auto dismiss any currently
18242 // showing dialogs?
18243 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18245 AttributeCache ac = AttributeCache.instance();
18247 ac.updateConfiguration(configCopy);
18250 // Make sure all resources in our process are updated
18251 // right now, so that anyone who is going to retrieve
18252 // resource values after we return will be sure to get
18253 // the new ones. This is especially important during
18254 // boot, where the first config change needs to guarantee
18255 // all resources have that config before following boot
18256 // code is executed.
18257 mSystemThread.applyConfigurationToResources(configCopy);
18259 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18260 Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18261 msg.obj = new Configuration(configCopy);
18263 mHandler.sendMessage(msg);
18266 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
18267 if (isDensityChange) {
18268 killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
18269 ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
18272 for (int i=mLruProcesses.size()-1; i>=0; i--) {
18273 ProcessRecord app = mLruProcesses.get(i);
18275 if (app.thread != null) {
18276 if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
18277 + app.processName + " new config " + mConfiguration);
18278 app.thread.scheduleConfigurationChanged(configCopy);
18280 } catch (Exception e) {
18283 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
18284 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
18285 | Intent.FLAG_RECEIVER_REPLACE_PENDING
18286 | Intent.FLAG_RECEIVER_FOREGROUND);
18287 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
18288 null, AppOpsManager.OP_NONE, null, false, false,
18289 MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18290 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
18291 intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
18292 intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
18293 if (!mProcessesReady) {
18294 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
18296 broadcastIntentLocked(null, null, intent,
18297 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
18298 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
18303 boolean kept = true;
18304 final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
18305 // mainStack is null during startup.
18306 if (mainStack != null) {
18307 if (changes != 0 && starting == null) {
18308 // If the configuration changed, and the caller is not already
18309 // in the process of starting an activity, then find the top
18310 // activity to check if its configuration needs to change.
18311 starting = mainStack.topRunningActivityLocked();
18314 if (starting != null) {
18315 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
18316 // And we need to make sure at this point that all other activities
18317 // are made visible with the correct configuration.
18318 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
18319 !PRESERVE_WINDOWS);
18323 if (values != null && mWindowManager != null) {
18324 mWindowManager.setNewConfiguration(mConfiguration);
18331 * Decide based on the configuration whether we should shouw the ANR,
18332 * crash, etc dialogs. The idea is that if there is no affordnace to
18333 * press the on-screen buttons, we shouldn't show the dialog.
18335 * A thought: SystemUI might also want to get told about this, the Power
18336 * dialog / global actions also might want different behaviors.
18338 private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
18339 final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
18340 && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
18341 && config.navigation == Configuration.NAVIGATION_NONAV);
18342 final boolean uiIsNotCarType = !((config.uiMode & Configuration.UI_MODE_TYPE_MASK)
18343 == Configuration.UI_MODE_TYPE_CAR);
18344 return inputMethodExists && uiIsNotCarType && !inVrMode;
18348 public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
18349 synchronized (this) {
18350 ActivityRecord srec = ActivityRecord.forTokenLocked(token);
18351 if (srec != null) {
18352 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
18358 public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
18359 Intent resultData) {
18361 synchronized (this) {
18362 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
18364 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
18370 public int getLaunchedFromUid(IBinder activityToken) {
18371 ActivityRecord srec;
18372 synchronized (this) {
18373 srec = ActivityRecord.forTokenLocked(activityToken);
18375 if (srec == null) {
18378 return srec.launchedFromUid;
18381 public String getLaunchedFromPackage(IBinder activityToken) {
18382 ActivityRecord srec;
18383 synchronized (this) {
18384 srec = ActivityRecord.forTokenLocked(activityToken);
18386 if (srec == null) {
18389 return srec.launchedFromPackage;
18392 // =========================================================
18393 // LIFETIME MANAGEMENT
18394 // =========================================================
18396 // Returns which broadcast queue the app is the current [or imminent] receiver
18397 // on, or 'null' if the app is not an active broadcast recipient.
18398 private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
18399 BroadcastRecord r = app.curReceiver;
18404 // It's not the current receiver, but it might be starting up to become one
18405 synchronized (this) {
18406 for (BroadcastQueue queue : mBroadcastQueues) {
18407 r = queue.mPendingBroadcast;
18408 if (r != null && r.curApp == app) {
18409 // found it; report which queue it's in
18418 Association startAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18419 ComponentName targetComponent, String targetProcess) {
18420 if (!mTrackingAssociations) {
18423 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18424 = mAssociations.get(targetUid);
18425 if (components == null) {
18426 components = new ArrayMap<>();
18427 mAssociations.put(targetUid, components);
18429 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18430 if (sourceUids == null) {
18431 sourceUids = new SparseArray<>();
18432 components.put(targetComponent, sourceUids);
18434 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18435 if (sourceProcesses == null) {
18436 sourceProcesses = new ArrayMap<>();
18437 sourceUids.put(sourceUid, sourceProcesses);
18439 Association ass = sourceProcesses.get(sourceProcess);
18441 ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
18443 sourceProcesses.put(sourceProcess, ass);
18447 if (ass.mNesting == 1) {
18448 ass.mStartTime = SystemClock.uptimeMillis();
18453 void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
18454 ComponentName targetComponent) {
18455 if (!mTrackingAssociations) {
18458 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
18459 = mAssociations.get(targetUid);
18460 if (components == null) {
18463 SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
18464 if (sourceUids == null) {
18467 ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
18468 if (sourceProcesses == null) {
18471 Association ass = sourceProcesses.get(sourceProcess);
18472 if (ass == null || ass.mNesting <= 0) {
18476 if (ass.mNesting == 0) {
18477 ass.mTime += SystemClock.uptimeMillis() - ass.mStartTime;
18481 private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
18482 boolean doingAll, long now) {
18483 if (mAdjSeq == app.adjSeq) {
18484 // This adjustment has already been computed.
18485 return app.curRawAdj;
18488 if (app.thread == null) {
18489 app.adjSeq = mAdjSeq;
18490 app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18491 app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18492 return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
18495 app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
18496 app.adjSource = null;
18497 app.adjTarget = null;
18499 app.cached = false;
18501 final int activitiesSize = app.activities.size();
18503 if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
18504 // The max adjustment doesn't allow this app to be anything
18505 // below foreground, so it is not worth doing work for it.
18506 app.adjType = "fixed";
18507 app.adjSeq = mAdjSeq;
18508 app.curRawAdj = app.maxAdj;
18509 app.foregroundActivities = false;
18510 app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18511 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
18512 // System processes can do UI, and when they do we want to have
18513 // them trim their memory after the user leaves the UI. To
18514 // facilitate this, here we need to determine whether or not it
18515 // is currently showing UI.
18516 app.systemNoUi = true;
18517 if (app == TOP_APP) {
18518 app.systemNoUi = false;
18519 } else if (activitiesSize > 0) {
18520 for (int j = 0; j < activitiesSize; j++) {
18521 final ActivityRecord r = app.activities.get(j);
18523 app.systemNoUi = false;
18527 if (!app.systemNoUi) {
18528 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
18530 return (app.curAdj=app.maxAdj);
18533 app.systemNoUi = false;
18535 final int PROCESS_STATE_CUR_TOP = mTopProcessState;
18537 // Determine the importance of the process, starting with most
18538 // important to least, and assign an appropriate OOM adjustment.
18542 boolean foregroundActivities = false;
18543 BroadcastQueue queue;
18544 if (app == TOP_APP) {
18545 // The last app on the list is the foreground app.
18546 adj = ProcessList.FOREGROUND_APP_ADJ;
18547 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18548 app.adjType = "top-activity";
18549 foregroundActivities = true;
18550 procState = PROCESS_STATE_CUR_TOP;
18551 } else if (app.instrumentationClass != null) {
18552 // Don't want to kill running instrumentation.
18553 adj = ProcessList.FOREGROUND_APP_ADJ;
18554 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18555 app.adjType = "instrumentation";
18556 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18557 } else if ((queue = isReceivingBroadcast(app)) != null) {
18558 // An app that is currently receiving a broadcast also
18559 // counts as being in the foreground for OOM killer purposes.
18560 // It's placed in a sched group based on the nature of the
18561 // broadcast as reflected by which queue it's active in.
18562 adj = ProcessList.FOREGROUND_APP_ADJ;
18563 schedGroup = (queue == mFgBroadcastQueue)
18564 ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18565 app.adjType = "broadcast";
18566 procState = ActivityManager.PROCESS_STATE_RECEIVER;
18567 } else if (app.executingServices.size() > 0) {
18568 // An app that is currently executing a service callback also
18569 // counts as being in the foreground.
18570 adj = ProcessList.FOREGROUND_APP_ADJ;
18571 schedGroup = app.execServicesFg ?
18572 ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
18573 app.adjType = "exec-service";
18574 procState = ActivityManager.PROCESS_STATE_SERVICE;
18575 //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
18577 // As far as we know the process is empty. We may change our mind later.
18578 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18579 // At this point we don't actually know the adjustment. Use the cached adj
18580 // value that the caller wants us to.
18582 procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18585 app.adjType = "cch-empty";
18588 // Examine all activities if not already foreground.
18589 if (!foregroundActivities && activitiesSize > 0) {
18590 int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
18591 for (int j = 0; j < activitiesSize; j++) {
18592 final ActivityRecord r = app.activities.get(j);
18593 if (r.app != app) {
18594 Slog.w(TAG, "Wtf, activity " + r + " in proc activity list not using proc "
18595 + app + "?!? Using " + r.app + " instead.");
18599 // App has a visible activity; only upgrade adjustment.
18600 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18601 adj = ProcessList.VISIBLE_APP_ADJ;
18602 app.adjType = "visible";
18604 if (procState > PROCESS_STATE_CUR_TOP) {
18605 procState = PROCESS_STATE_CUR_TOP;
18607 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18608 app.cached = false;
18610 foregroundActivities = true;
18611 if (r.task != null && minLayer > 0) {
18612 final int layer = r.task.mLayerRank;
18613 if (layer >= 0 && minLayer > layer) {
18618 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
18619 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18620 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18621 app.adjType = "pausing";
18623 if (procState > PROCESS_STATE_CUR_TOP) {
18624 procState = PROCESS_STATE_CUR_TOP;
18626 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18627 app.cached = false;
18629 foregroundActivities = true;
18630 } else if (r.state == ActivityState.STOPPING) {
18631 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18632 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18633 app.adjType = "stopping";
18635 // For the process state, we will at this point consider the
18636 // process to be cached. It will be cached either as an activity
18637 // or empty depending on whether the activity is finishing. We do
18638 // this so that we can treat the process as cached for purposes of
18639 // memory trimming (determing current memory level, trim command to
18640 // send to process) since there can be an arbitrary number of stopping
18641 // processes and they should soon all go into the cached state.
18642 if (!r.finishing) {
18643 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18644 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18647 app.cached = false;
18649 foregroundActivities = true;
18651 if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18652 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
18653 app.adjType = "cch-act";
18657 if (adj == ProcessList.VISIBLE_APP_ADJ) {
18662 if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
18663 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
18664 if (app.foregroundServices) {
18665 // The user is aware of this app, so make it visible.
18666 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18667 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
18668 app.cached = false;
18669 app.adjType = "fg-service";
18670 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18671 } else if (app.forcingToForeground != null) {
18672 // The user is aware of this app, so make it visible.
18673 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18674 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18675 app.cached = false;
18676 app.adjType = "force-fg";
18677 app.adjSource = app.forcingToForeground;
18678 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18682 if (app == mHeavyWeightProcess) {
18683 if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
18684 // We don't want to kill the current heavy-weight process.
18685 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
18686 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18687 app.cached = false;
18688 app.adjType = "heavy";
18690 if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
18691 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
18695 if (app == mHomeProcess) {
18696 if (adj > ProcessList.HOME_APP_ADJ) {
18697 // This process is hosting what we currently consider to be the
18698 // home app, so we don't want to let it go into the background.
18699 adj = ProcessList.HOME_APP_ADJ;
18700 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18701 app.cached = false;
18702 app.adjType = "home";
18704 if (procState > ActivityManager.PROCESS_STATE_HOME) {
18705 procState = ActivityManager.PROCESS_STATE_HOME;
18709 if (app == mPreviousProcess && app.activities.size() > 0) {
18710 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
18711 // This was the previous process that showed UI to the user.
18712 // We want to try to keep it around more aggressively, to give
18713 // a good experience around switching between two apps.
18714 adj = ProcessList.PREVIOUS_APP_ADJ;
18715 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
18716 app.cached = false;
18717 app.adjType = "previous";
18719 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
18720 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
18724 if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
18725 + " reason=" + app.adjType);
18727 // By default, we use the computed adjustment. It may be changed if
18728 // there are applications dependent on our services or providers, but
18729 // this gives us a baseline and makes sure we don't get into an
18730 // infinite recursion.
18731 app.adjSeq = mAdjSeq;
18732 app.curRawAdj = adj;
18733 app.hasStartedServices = false;
18735 if (mBackupTarget != null && app == mBackupTarget.app) {
18736 // If possible we want to avoid killing apps while they're being backed up
18737 if (adj > ProcessList.BACKUP_APP_ADJ) {
18738 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
18739 adj = ProcessList.BACKUP_APP_ADJ;
18740 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18741 procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18743 app.adjType = "backup";
18744 app.cached = false;
18746 if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
18747 procState = ActivityManager.PROCESS_STATE_BACKUP;
18751 boolean mayBeTop = false;
18753 for (int is = app.services.size()-1;
18754 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18755 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18756 || procState > ActivityManager.PROCESS_STATE_TOP);
18758 ServiceRecord s = app.services.valueAt(is);
18759 if (s.startRequested) {
18760 app.hasStartedServices = true;
18761 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
18762 procState = ActivityManager.PROCESS_STATE_SERVICE;
18764 if (app.hasShownUi && app != mHomeProcess) {
18765 // If this process has shown some UI, let it immediately
18766 // go to the LRU list because it may be pretty heavy with
18767 // UI stuff. We'll tag it with a label just to help
18768 // debug and understand what is going on.
18769 if (adj > ProcessList.SERVICE_ADJ) {
18770 app.adjType = "cch-started-ui-services";
18773 if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18774 // This service has seen some activity within
18775 // recent memory, so we will keep its process ahead
18776 // of the background processes.
18777 if (adj > ProcessList.SERVICE_ADJ) {
18778 adj = ProcessList.SERVICE_ADJ;
18779 app.adjType = "started-services";
18780 app.cached = false;
18783 // If we have let the service slide into the background
18784 // state, still have some text describing what it is doing
18785 // even though the service no longer has an impact.
18786 if (adj > ProcessList.SERVICE_ADJ) {
18787 app.adjType = "cch-started-services";
18791 for (int conni = s.connections.size()-1;
18792 conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18793 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18794 || procState > ActivityManager.PROCESS_STATE_TOP);
18796 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
18798 i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
18799 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18800 || procState > ActivityManager.PROCESS_STATE_TOP);
18802 // XXX should compute this based on the max of
18803 // all connected clients.
18804 ConnectionRecord cr = clist.get(i);
18805 if (cr.binding.client == app) {
18806 // Binding to ourself is not interesting.
18809 if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
18810 ProcessRecord client = cr.binding.client;
18811 int clientAdj = computeOomAdjLocked(client, cachedAdj,
18812 TOP_APP, doingAll, now);
18813 int clientProcState = client.curProcState;
18814 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18815 // If the other app is cached for any reason, for purposes here
18816 // we are going to consider it empty. The specific cached state
18817 // doesn't propagate except under certain conditions.
18818 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18820 String adjType = null;
18821 if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
18822 // Not doing bind OOM management, so treat
18823 // this guy more like a started service.
18824 if (app.hasShownUi && app != mHomeProcess) {
18825 // If this process has shown some UI, let it immediately
18826 // go to the LRU list because it may be pretty heavy with
18827 // UI stuff. We'll tag it with a label just to help
18828 // debug and understand what is going on.
18829 if (adj > clientAdj) {
18830 adjType = "cch-bound-ui-services";
18832 app.cached = false;
18834 clientProcState = procState;
18836 if (now >= (s.lastActivity
18837 + ActiveServices.MAX_SERVICE_INACTIVITY)) {
18838 // This service has not seen activity within
18839 // recent memory, so allow it to drop to the
18840 // LRU list if there is no other reason to keep
18841 // it around. We'll also tag it with a label just
18842 // to help debug and undertand what is going on.
18843 if (adj > clientAdj) {
18844 adjType = "cch-bound-services";
18850 if (adj > clientAdj) {
18851 // If this process has recently shown UI, and
18852 // the process that is binding to it is less
18853 // important than being visible, then we don't
18854 // care about the binding as much as we care
18855 // about letting this process get into the LRU
18856 // list to be killed and restarted if needed for
18858 if (app.hasShownUi && app != mHomeProcess
18859 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18860 adjType = "cch-bound-ui-services";
18862 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
18863 |Context.BIND_IMPORTANT)) != 0) {
18864 adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
18865 ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
18866 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
18867 && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
18868 && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
18869 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
18870 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
18873 if (adj > ProcessList.VISIBLE_APP_ADJ) {
18874 adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
18877 if (!client.cached) {
18878 app.cached = false;
18880 adjType = "service";
18883 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18884 // This will treat important bound services identically to
18885 // the top app, which may behave differently than generic
18886 // foreground work.
18887 if (client.curSchedGroup > schedGroup) {
18888 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18889 schedGroup = client.curSchedGroup;
18891 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18894 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
18895 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
18896 // Special handling of clients who are in the top state.
18897 // We *may* want to consider this process to be in the
18898 // top state as well, but only if there is not another
18899 // reason for it to be running. Being on the top is a
18900 // special state, meaning you are specifically running
18901 // for the current top app. If the process is already
18902 // running in the background for some other reason, it
18903 // is more important to continue considering it to be
18904 // in the background state.
18906 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
18908 // Special handling for above-top states (persistent
18909 // processes). These should not bring the current process
18910 // into the top state, since they are not on top. Instead
18911 // give them the best state after that.
18912 if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
18914 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18915 } else if (mWakefulness
18916 == PowerManagerInternal.WAKEFULNESS_AWAKE &&
18917 (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
18920 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
18923 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
18928 if (clientProcState <
18929 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
18931 ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
18934 if (procState > clientProcState) {
18935 procState = clientProcState;
18937 if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
18938 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
18939 app.pendingUiClean = true;
18941 if (adjType != null) {
18942 app.adjType = adjType;
18943 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18944 .REASON_SERVICE_IN_USE;
18945 app.adjSource = cr.binding.client;
18946 app.adjSourceProcState = clientProcState;
18947 app.adjTarget = s.name;
18950 if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
18951 app.treatLikeActivity = true;
18953 final ActivityRecord a = cr.activity;
18954 if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
18955 if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
18956 (a.visible || a.state == ActivityState.RESUMED ||
18957 a.state == ActivityState.PAUSING)) {
18958 adj = ProcessList.FOREGROUND_APP_ADJ;
18959 if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
18960 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
18961 schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
18963 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
18966 app.cached = false;
18967 app.adjType = "service";
18968 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
18969 .REASON_SERVICE_IN_USE;
18971 app.adjSourceProcState = procState;
18972 app.adjTarget = s.name;
18979 for (int provi = app.pubProviders.size()-1;
18980 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18981 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18982 || procState > ActivityManager.PROCESS_STATE_TOP);
18984 ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
18985 for (int i = cpr.connections.size()-1;
18986 i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
18987 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
18988 || procState > ActivityManager.PROCESS_STATE_TOP);
18990 ContentProviderConnection conn = cpr.connections.get(i);
18991 ProcessRecord client = conn.client;
18992 if (client == app) {
18993 // Being our own client is not interesting.
18996 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
18997 int clientProcState = client.curProcState;
18998 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
18999 // If the other app is cached for any reason, for purposes here
19000 // we are going to consider it empty.
19001 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19003 if (adj > clientAdj) {
19004 if (app.hasShownUi && app != mHomeProcess
19005 && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19006 app.adjType = "cch-ui-provider";
19008 adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19009 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19010 app.adjType = "provider";
19012 app.cached &= client.cached;
19013 app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19014 .REASON_PROVIDER_IN_USE;
19015 app.adjSource = client;
19016 app.adjSourceProcState = clientProcState;
19017 app.adjTarget = cpr.name;
19019 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19020 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19021 // Special handling of clients who are in the top state.
19022 // We *may* want to consider this process to be in the
19023 // top state as well, but only if there is not another
19024 // reason for it to be running. Being on the top is a
19025 // special state, meaning you are specifically running
19026 // for the current top app. If the process is already
19027 // running in the background for some other reason, it
19028 // is more important to continue considering it to be
19029 // in the background state.
19031 clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19033 // Special handling for above-top states (persistent
19034 // processes). These should not bring the current process
19035 // into the top state, since they are not on top. Instead
19036 // give them the best state after that.
19038 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19041 if (procState > clientProcState) {
19042 procState = clientProcState;
19044 if (client.curSchedGroup > schedGroup) {
19045 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19048 // If the provider has external (non-framework) process
19049 // dependencies, ensure that its adjustment is at least
19050 // FOREGROUND_APP_ADJ.
19051 if (cpr.hasExternalProcessHandles()) {
19052 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19053 adj = ProcessList.FOREGROUND_APP_ADJ;
19054 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19055 app.cached = false;
19056 app.adjType = "provider";
19057 app.adjTarget = cpr.name;
19059 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19060 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19065 if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19066 if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19067 adj = ProcessList.PREVIOUS_APP_ADJ;
19068 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19069 app.cached = false;
19070 app.adjType = "provider";
19072 if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19073 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19077 if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19078 // A client of one of our services or providers is in the top state. We
19079 // *may* want to be in the top state, but not if we are already running in
19080 // the background for some other reason. For the decision here, we are going
19081 // to pick out a few specific states that we want to remain in when a client
19082 // is top (states that tend to be longer-term) and otherwise allow it to go
19083 // to the top state.
19084 switch (procState) {
19085 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19086 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19087 case ActivityManager.PROCESS_STATE_SERVICE:
19088 // These all are longer-term states, so pull them up to the top
19089 // of the background states, but not all the way to the top state.
19090 procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19093 // Otherwise, top is a better choice, so take it.
19094 procState = ActivityManager.PROCESS_STATE_TOP;
19099 if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19100 if (app.hasClientActivities) {
19101 // This is a cached process, but with client activities. Mark it so.
19102 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19103 app.adjType = "cch-client-act";
19104 } else if (app.treatLikeActivity) {
19105 // This is a cached process, but somebody wants us to treat it like it has
19106 // an activity, okay!
19107 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19108 app.adjType = "cch-as-act";
19112 if (adj == ProcessList.SERVICE_ADJ) {
19114 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19115 mNewNumServiceProcs++;
19116 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19117 if (!app.serviceb) {
19118 // This service isn't far enough down on the LRU list to
19119 // normally be a B service, but if we are low on RAM and it
19120 // is large we want to force it down since we would prefer to
19121 // keep launcher over it.
19122 if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19123 && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19124 app.serviceHighRam = true;
19125 app.serviceb = true;
19126 //Slog.i(TAG, "ADJ " + app + " high ram!");
19128 mNewNumAServiceProcs++;
19129 //Slog.i(TAG, "ADJ " + app + " not high ram!");
19132 app.serviceHighRam = false;
19135 if (app.serviceb) {
19136 adj = ProcessList.SERVICE_B_ADJ;
19140 app.curRawAdj = adj;
19142 //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19143 // " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19144 if (adj > app.maxAdj) {
19146 if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19147 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19151 // Do final modification to adj. Everything we do between here and applying
19152 // the final setAdj must be done in this function, because we will also use
19153 // it when computing the final cached adj later. Note that we don't need to
19154 // worry about this for max adj above, since max adj will always be used to
19155 // keep it out of the cached vaues.
19156 app.curAdj = app.modifyRawOomAdj(adj);
19157 app.curSchedGroup = schedGroup;
19158 app.curProcState = procState;
19159 app.foregroundActivities = foregroundActivities;
19161 return app.curRawAdj;
19165 * Record new PSS sample for a process.
19167 void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19169 EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19171 proc.lastPssTime = now;
19172 proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19173 if (DEBUG_PSS) Slog.d(TAG_PSS,
19174 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19175 + " state=" + ProcessList.makeProcStateString(procState));
19176 if (proc.initialIdlePss == 0) {
19177 proc.initialIdlePss = pss;
19179 proc.lastPss = pss;
19180 proc.lastSwapPss = swapPss;
19181 if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19182 proc.lastCachedPss = pss;
19183 proc.lastCachedSwapPss = swapPss;
19186 final SparseArray<Pair<Long, String>> watchUids
19187 = mMemWatchProcesses.getMap().get(proc.processName);
19189 if (watchUids != null) {
19190 Pair<Long, String> val = watchUids.get(proc.uid);
19192 val = watchUids.get(0);
19198 if (check != null) {
19199 if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19200 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
19201 if (!isDebuggable) {
19202 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
19203 isDebuggable = true;
19206 if (isDebuggable) {
19207 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
19208 final ProcessRecord myProc = proc;
19209 final File heapdumpFile = DumpHeapProvider.getJavaFile();
19210 mMemWatchDumpProcName = proc.processName;
19211 mMemWatchDumpFile = heapdumpFile.toString();
19212 mMemWatchDumpPid = proc.pid;
19213 mMemWatchDumpUid = proc.uid;
19214 BackgroundThread.getHandler().post(new Runnable() {
19216 public void run() {
19217 revokeUriPermission(ActivityThread.currentActivityThread()
19218 .getApplicationThread(),
19219 DumpHeapActivity.JAVA_URI,
19220 Intent.FLAG_GRANT_READ_URI_PERMISSION
19221 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
19222 UserHandle.myUserId());
19223 ParcelFileDescriptor fd = null;
19225 heapdumpFile.delete();
19226 fd = ParcelFileDescriptor.open(heapdumpFile,
19227 ParcelFileDescriptor.MODE_CREATE |
19228 ParcelFileDescriptor.MODE_TRUNCATE |
19229 ParcelFileDescriptor.MODE_WRITE_ONLY |
19230 ParcelFileDescriptor.MODE_APPEND);
19231 IApplicationThread thread = myProc.thread;
19232 if (thread != null) {
19234 if (DEBUG_PSS) Slog.d(TAG_PSS,
19235 "Requesting dump heap from "
19236 + myProc + " to " + heapdumpFile);
19237 thread.dumpHeap(true, heapdumpFile.toString(), fd);
19238 } catch (RemoteException e) {
19241 } catch (FileNotFoundException e) {
19242 e.printStackTrace();
19247 } catch (IOException e) {
19254 Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
19255 + ", but debugging not enabled");
19262 * Schedule PSS collection of a process.
19264 void requestPssLocked(ProcessRecord proc, int procState) {
19265 if (mPendingPssProcesses.contains(proc)) {
19268 if (mPendingPssProcesses.size() == 0) {
19269 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19271 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
19272 proc.pssProcState = procState;
19273 mPendingPssProcesses.add(proc);
19277 * Schedule PSS collection of all processes.
19279 void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
19281 if (now < (mLastFullPssTime +
19282 (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
19286 if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs! memLowered=" + memLowered);
19287 mLastFullPssTime = now;
19288 mFullPssPending = true;
19289 mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
19290 mPendingPssProcesses.clear();
19291 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
19292 ProcessRecord app = mLruProcesses.get(i);
19293 if (app.thread == null
19294 || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
19297 if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
19298 app.pssProcState = app.setProcState;
19299 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19300 mTestPssMode, isSleeping(), now);
19301 mPendingPssProcesses.add(app);
19304 mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
19307 public void setTestPssMode(boolean enabled) {
19308 synchronized (this) {
19309 mTestPssMode = enabled;
19311 // Whenever we enable the mode, we want to take a snapshot all of current
19312 // process mem use.
19313 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
19319 * Ask a given process to GC right now.
19321 final void performAppGcLocked(ProcessRecord app) {
19323 app.lastRequestedGc = SystemClock.uptimeMillis();
19324 if (app.thread != null) {
19325 if (app.reportLowMemory) {
19326 app.reportLowMemory = false;
19327 app.thread.scheduleLowMemory();
19329 app.thread.processInBackground();
19332 } catch (Exception e) {
19338 * Returns true if things are idle enough to perform GCs.
19340 private final boolean canGcNowLocked() {
19341 boolean processingBroadcasts = false;
19342 for (BroadcastQueue q : mBroadcastQueues) {
19343 if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
19344 processingBroadcasts = true;
19347 return !processingBroadcasts
19348 && (isSleeping() || mStackSupervisor.allResumedActivitiesIdle());
19352 * Perform GCs on all processes that are waiting for it, but only
19353 * if things are idle.
19355 final void performAppGcsLocked() {
19356 final int N = mProcessesToGc.size();
19360 if (canGcNowLocked()) {
19361 while (mProcessesToGc.size() > 0) {
19362 ProcessRecord proc = mProcessesToGc.remove(0);
19363 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
19364 if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
19365 <= SystemClock.uptimeMillis()) {
19366 // To avoid spamming the system, we will GC processes one
19367 // at a time, waiting a few seconds between each.
19368 performAppGcLocked(proc);
19369 scheduleAppGcsLocked();
19372 // It hasn't been long enough since we last GCed this
19373 // process... put it in the list to wait for its time.
19374 addProcessToGcListLocked(proc);
19380 scheduleAppGcsLocked();
19385 * If all looks good, perform GCs on all processes waiting for them.
19387 final void performAppGcsIfAppropriateLocked() {
19388 if (canGcNowLocked()) {
19389 performAppGcsLocked();
19392 // Still not idle, wait some more.
19393 scheduleAppGcsLocked();
19397 * Schedule the execution of all pending app GCs.
19399 final void scheduleAppGcsLocked() {
19400 mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
19402 if (mProcessesToGc.size() > 0) {
19403 // Schedule a GC for the time to the next process.
19404 ProcessRecord proc = mProcessesToGc.get(0);
19405 Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
19407 long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
19408 long now = SystemClock.uptimeMillis();
19409 if (when < (now+GC_TIMEOUT)) {
19410 when = now + GC_TIMEOUT;
19412 mHandler.sendMessageAtTime(msg, when);
19417 * Add a process to the array of processes waiting to be GCed. Keeps the
19418 * list in sorted order by the last GC time. The process can't already be
19421 final void addProcessToGcListLocked(ProcessRecord proc) {
19422 boolean added = false;
19423 for (int i=mProcessesToGc.size()-1; i>=0; i--) {
19424 if (mProcessesToGc.get(i).lastRequestedGc <
19425 proc.lastRequestedGc) {
19427 mProcessesToGc.add(i+1, proc);
19432 mProcessesToGc.add(0, proc);
19437 * Set up to ask a process to GC itself. This will either do it
19438 * immediately, or put it on the list of processes to gc the next
19439 * time things are idle.
19441 final void scheduleAppGcLocked(ProcessRecord app) {
19442 long now = SystemClock.uptimeMillis();
19443 if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
19446 if (!mProcessesToGc.contains(app)) {
19447 addProcessToGcListLocked(app);
19448 scheduleAppGcsLocked();
19452 final void checkExcessivePowerUsageLocked(boolean doKills) {
19453 updateCpuStatsNow();
19455 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19456 boolean doWakeKills = doKills;
19457 boolean doCpuKills = doKills;
19458 if (mLastPowerCheckRealtime == 0) {
19459 doWakeKills = false;
19461 if (mLastPowerCheckUptime == 0) {
19462 doCpuKills = false;
19464 if (stats.isScreenOn()) {
19465 doWakeKills = false;
19467 final long curRealtime = SystemClock.elapsedRealtime();
19468 final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
19469 final long curUptime = SystemClock.uptimeMillis();
19470 final long uptimeSince = curUptime - mLastPowerCheckUptime;
19471 mLastPowerCheckRealtime = curRealtime;
19472 mLastPowerCheckUptime = curUptime;
19473 if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
19474 doWakeKills = false;
19476 if (uptimeSince < CPU_MIN_CHECK_DURATION) {
19477 doCpuKills = false;
19479 int i = mLruProcesses.size();
19482 ProcessRecord app = mLruProcesses.get(i);
19483 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19485 synchronized (stats) {
19486 wtime = stats.getProcessWakeTime(app.info.uid,
19487 app.pid, curRealtime);
19489 long wtimeUsed = wtime - app.lastWakeTime;
19490 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
19492 StringBuilder sb = new StringBuilder(128);
19493 sb.append("Wake for ");
19494 app.toShortString(sb);
19495 sb.append(": over ");
19496 TimeUtils.formatDuration(realtimeSince, sb);
19497 sb.append(" used ");
19498 TimeUtils.formatDuration(wtimeUsed, sb);
19500 sb.append((wtimeUsed*100)/realtimeSince);
19502 Slog.i(TAG_POWER, sb.toString());
19504 sb.append("CPU for ");
19505 app.toShortString(sb);
19506 sb.append(": over ");
19507 TimeUtils.formatDuration(uptimeSince, sb);
19508 sb.append(" used ");
19509 TimeUtils.formatDuration(cputimeUsed, sb);
19511 sb.append((cputimeUsed*100)/uptimeSince);
19513 Slog.i(TAG_POWER, sb.toString());
19515 // If a process has held a wake lock for more
19516 // than 50% of the time during this period,
19517 // that sounds bad. Kill!
19518 if (doWakeKills && realtimeSince > 0
19519 && ((wtimeUsed*100)/realtimeSince) >= 50) {
19520 synchronized (stats) {
19521 stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
19522 realtimeSince, wtimeUsed);
19524 app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
19525 app.baseProcessTracker.reportExcessiveWake(app.pkgList);
19526 } else if (doCpuKills && uptimeSince > 0
19527 && ((cputimeUsed*100)/uptimeSince) >= 25) {
19528 synchronized (stats) {
19529 stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
19530 uptimeSince, cputimeUsed);
19532 app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
19533 app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
19535 app.lastWakeTime = wtime;
19536 app.lastCpuTime = app.curCpuTime;
19542 private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
19544 boolean success = true;
19546 if (app.curRawAdj != app.setRawAdj) {
19547 app.setRawAdj = app.curRawAdj;
19552 if (app.curAdj != app.setAdj) {
19553 ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
19554 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19555 "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
19557 app.setAdj = app.curAdj;
19560 if (app.setSchedGroup != app.curSchedGroup) {
19561 app.setSchedGroup = app.curSchedGroup;
19562 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19563 "Setting sched group of " + app.processName
19564 + " to " + app.curSchedGroup);
19565 if (app.waitingToKill != null && app.curReceiver == null
19566 && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
19567 app.kill(app.waitingToKill, true);
19571 switch (app.curSchedGroup) {
19572 case ProcessList.SCHED_GROUP_BACKGROUND:
19573 processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
19575 case ProcessList.SCHED_GROUP_TOP_APP:
19576 processGroup = Process.THREAD_GROUP_TOP_APP;
19579 processGroup = Process.THREAD_GROUP_DEFAULT;
19583 long oldId = Binder.clearCallingIdentity();
19585 Process.setProcessGroup(app.pid, processGroup);
19586 } catch (Exception e) {
19587 Slog.w(TAG, "Failed setting process group of " + app.pid
19588 + " to " + app.curSchedGroup);
19589 e.printStackTrace();
19591 Binder.restoreCallingIdentity(oldId);
19594 if (app.thread != null) {
19596 app.thread.setSchedulingGroup(processGroup);
19597 } catch (RemoteException e) {
19603 if (app.repForegroundActivities != app.foregroundActivities) {
19604 app.repForegroundActivities = app.foregroundActivities;
19605 changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
19607 if (app.repProcState != app.curProcState) {
19608 app.repProcState = app.curProcState;
19609 changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
19610 if (app.thread != null) {
19613 //RuntimeException h = new RuntimeException("here");
19614 Slog.i(TAG, "Sending new process state " + app.repProcState
19615 + " to " + app /*, h*/);
19617 app.thread.setProcessState(app.repProcState);
19618 } catch (RemoteException e) {
19622 if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
19623 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
19624 if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
19625 // Experimental code to more aggressively collect pss while
19626 // running test... the problem is that this tends to collect
19627 // the data right when a process is transitioning between process
19628 // states, which well tend to give noisy data.
19629 long start = SystemClock.uptimeMillis();
19630 long pss = Debug.getPss(app.pid, mTmpLong, null);
19631 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
19632 mPendingPssProcesses.remove(app);
19633 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
19634 + " to " + app.curProcState + ": "
19635 + (SystemClock.uptimeMillis()-start) + "ms");
19637 app.lastStateTime = now;
19638 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
19639 mTestPssMode, isSleeping(), now);
19640 if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
19641 + ProcessList.makeProcStateString(app.setProcState) + " to "
19642 + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
19643 + (app.nextPssTime-now) + ": " + app);
19645 if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
19646 && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
19648 requestPssLocked(app, app.setProcState);
19649 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
19650 mTestPssMode, isSleeping(), now);
19651 } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
19652 "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
19654 if (app.setProcState != app.curProcState) {
19655 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
19656 "Proc state change of " + app.processName
19657 + " to " + app.curProcState);
19658 boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
19659 boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
19660 if (setImportant && !curImportant) {
19661 // This app is no longer something we consider important enough to allow to
19662 // use arbitrary amounts of battery power. Note
19663 // its current wake lock time to later know to kill it if
19664 // it is not behaving well.
19665 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
19666 synchronized (stats) {
19667 app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
19668 app.pid, nowElapsed);
19670 app.lastCpuTime = app.curCpuTime;
19673 // Inform UsageStats of important process state change
19674 // Must be called before updating setProcState
19675 maybeUpdateUsageStatsLocked(app, nowElapsed);
19677 app.setProcState = app.curProcState;
19678 if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
19679 app.notCachedSinceIdle = false;
19682 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
19684 app.procStateChanged = true;
19686 } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
19687 > USAGE_STATS_INTERACTION_INTERVAL) {
19688 // For apps that sit around for a long time in the interactive state, we need
19689 // to report this at least once a day so they don't go idle.
19690 maybeUpdateUsageStatsLocked(app, nowElapsed);
19693 if (changes != 0) {
19694 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19695 "Changes in " + app + ": " + changes);
19696 int i = mPendingProcessChanges.size()-1;
19697 ProcessChangeItem item = null;
19699 item = mPendingProcessChanges.get(i);
19700 if (item.pid == app.pid) {
19701 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19702 "Re-using existing item: " + item);
19708 // No existing item in pending changes; need a new one.
19709 final int NA = mAvailProcessChanges.size();
19711 item = mAvailProcessChanges.remove(NA-1);
19712 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19713 "Retrieving available item: " + item);
19715 item = new ProcessChangeItem();
19716 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19717 "Allocating new item: " + item);
19720 item.pid = app.pid;
19721 item.uid = app.info.uid;
19722 if (mPendingProcessChanges.size() == 0) {
19723 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19724 "*** Enqueueing dispatch processes changed!");
19725 mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
19727 mPendingProcessChanges.add(item);
19729 item.changes |= changes;
19730 item.processState = app.repProcState;
19731 item.foregroundActivities = app.repForegroundActivities;
19732 if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
19733 "Item " + Integer.toHexString(System.identityHashCode(item))
19734 + " " + app.toShortString() + ": changes=" + item.changes
19735 + " procState=" + item.processState
19736 + " foreground=" + item.foregroundActivities
19737 + " type=" + app.adjType + " source=" + app.adjSource
19738 + " target=" + app.adjTarget);
19744 private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
19745 final UidRecord.ChangeItem pendingChange;
19746 if (uidRec == null || uidRec.pendingChange == null) {
19747 if (mPendingUidChanges.size() == 0) {
19748 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19749 "*** Enqueueing dispatch uid changed!");
19750 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
19752 final int NA = mAvailUidChanges.size();
19754 pendingChange = mAvailUidChanges.remove(NA-1);
19755 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19756 "Retrieving available item: " + pendingChange);
19758 pendingChange = new UidRecord.ChangeItem();
19759 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19760 "Allocating new item: " + pendingChange);
19762 if (uidRec != null) {
19763 uidRec.pendingChange = pendingChange;
19764 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
19765 // If this uid is going away, and we haven't yet reported it is gone,
19767 change = UidRecord.CHANGE_GONE_IDLE;
19769 } else if (uid < 0) {
19770 throw new IllegalArgumentException("No UidRecord or uid");
19772 pendingChange.uidRecord = uidRec;
19773 pendingChange.uid = uidRec != null ? uidRec.uid : uid;
19774 mPendingUidChanges.add(pendingChange);
19776 pendingChange = uidRec.pendingChange;
19777 if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
19778 change = UidRecord.CHANGE_GONE_IDLE;
19781 pendingChange.change = change;
19782 pendingChange.processState = uidRec != null
19783 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
19786 private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
19787 String authority) {
19788 if (app == null) return;
19789 if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19790 UserState userState = mUserController.getStartedUserStateLocked(app.userId);
19791 if (userState == null) return;
19792 final long now = SystemClock.elapsedRealtime();
19793 Long lastReported = userState.mProviderLastReportedFg.get(authority);
19794 if (lastReported == null || lastReported < now - 60 * 1000L) {
19795 mUsageStatsService.reportContentProviderUsage(
19796 authority, providerPkgName, app.userId);
19797 userState.mProviderLastReportedFg.put(authority, now);
19802 private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
19803 if (DEBUG_USAGE_STATS) {
19804 Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
19805 + "] state changes: old = " + app.setProcState + ", new = "
19806 + app.curProcState);
19808 if (mUsageStatsService == null) {
19811 boolean isInteraction;
19812 // To avoid some abuse patterns, we are going to be careful about what we consider
19813 // to be an app interaction. Being the top activity doesn't count while the display
19814 // is sleeping, nor do short foreground services.
19815 if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
19816 isInteraction = true;
19817 app.fgInteractionTime = 0;
19818 } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
19819 if (app.fgInteractionTime == 0) {
19820 app.fgInteractionTime = nowElapsed;
19821 isInteraction = false;
19823 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
19826 isInteraction = app.curProcState
19827 <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19828 app.fgInteractionTime = 0;
19830 if (isInteraction && (!app.reportedInteraction
19831 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
19832 app.interactionEventTime = nowElapsed;
19833 String[] packages = app.getPackageList();
19834 if (packages != null) {
19835 for (int i = 0; i < packages.length; i++) {
19836 mUsageStatsService.reportEvent(packages[i], app.userId,
19837 UsageEvents.Event.SYSTEM_INTERACTION);
19841 app.reportedInteraction = isInteraction;
19842 if (!isInteraction) {
19843 app.interactionEventTime = 0;
19847 private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
19848 if (proc.thread != null) {
19849 if (proc.baseProcessTracker != null) {
19850 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
19855 private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
19856 ProcessRecord TOP_APP, boolean doingAll, long now) {
19857 if (app.thread == null) {
19861 computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
19863 return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
19866 final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
19868 if (isForeground != proc.foregroundServices) {
19869 proc.foregroundServices = isForeground;
19870 ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
19872 if (isForeground) {
19873 if (curProcs == null) {
19874 curProcs = new ArrayList<ProcessRecord>();
19875 mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
19877 if (!curProcs.contains(proc)) {
19878 curProcs.add(proc);
19879 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
19880 proc.info.packageName, proc.info.uid);
19883 if (curProcs != null) {
19884 if (curProcs.remove(proc)) {
19885 mBatteryStatsService.noteEvent(
19886 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
19887 proc.info.packageName, proc.info.uid);
19888 if (curProcs.size() <= 0) {
19889 mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
19895 updateOomAdjLocked();
19900 private final ActivityRecord resumedAppLocked() {
19901 ActivityRecord act = mStackSupervisor.resumedAppLocked();
19905 pkg = act.packageName;
19906 uid = act.info.applicationInfo.uid;
19911 // Has the UID or resumed package name changed?
19912 if (uid != mCurResumedUid || (pkg != mCurResumedPackage
19913 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
19914 if (mCurResumedPackage != null) {
19915 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
19916 mCurResumedPackage, mCurResumedUid);
19918 mCurResumedPackage = pkg;
19919 mCurResumedUid = uid;
19920 if (mCurResumedPackage != null) {
19921 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
19922 mCurResumedPackage, mCurResumedUid);
19928 final boolean updateOomAdjLocked(ProcessRecord app) {
19929 final ActivityRecord TOP_ACT = resumedAppLocked();
19930 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19931 final boolean wasCached = app.cached;
19935 // This is the desired cached adjusment we want to tell it to use.
19936 // If our app is currently cached, we know it, and that is it. Otherwise,
19937 // we don't know it yet, and it needs to now be cached we will then
19938 // need to do a complete oom adj.
19939 final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
19940 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
19941 boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
19942 SystemClock.uptimeMillis());
19943 if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
19944 // Changed to/from cached state, so apps after it in the LRU
19945 // list may also be changed.
19946 updateOomAdjLocked();
19951 final void updateOomAdjLocked() {
19952 final ActivityRecord TOP_ACT = resumedAppLocked();
19953 final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
19954 final long now = SystemClock.uptimeMillis();
19955 final long nowElapsed = SystemClock.elapsedRealtime();
19956 final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
19957 final int N = mLruProcesses.size();
19960 RuntimeException e = new RuntimeException();
19961 e.fillInStackTrace();
19962 Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
19965 // Reset state in all uid records.
19966 for (int i=mActiveUids.size()-1; i>=0; i--) {
19967 final UidRecord uidRec = mActiveUids.valueAt(i);
19968 if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
19969 "Starting update of " + uidRec);
19973 mStackSupervisor.rankTaskLayersIfNeeded();
19976 mNewNumServiceProcs = 0;
19977 mNewNumAServiceProcs = 0;
19979 final int emptyProcessLimit;
19980 final int cachedProcessLimit;
19981 if (mProcessLimit <= 0) {
19982 emptyProcessLimit = cachedProcessLimit = 0;
19983 } else if (mProcessLimit == 1) {
19984 emptyProcessLimit = 1;
19985 cachedProcessLimit = 0;
19987 emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
19988 cachedProcessLimit = mProcessLimit - emptyProcessLimit;
19991 // Let's determine how many processes we have running vs.
19992 // how many slots we have for background processes; we may want
19993 // to put multiple processes in a slot of there are enough of
19995 int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
19996 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
19997 int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
19998 if (numEmptyProcs > cachedProcessLimit) {
19999 // If there are more empty processes than our limit on cached
20000 // processes, then use the cached process limit for the factor.
20001 // This ensures that the really old empty processes get pushed
20002 // down to the bottom, so if we are running low on memory we will
20003 // have a better chance at keeping around more cached processes
20004 // instead of a gazillion empty processes.
20005 numEmptyProcs = cachedProcessLimit;
20007 int emptyFactor = numEmptyProcs/numSlots;
20008 if (emptyFactor < 1) emptyFactor = 1;
20009 int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20010 if (cachedFactor < 1) cachedFactor = 1;
20011 int stepCached = 0;
20015 int numTrimming = 0;
20017 mNumNonCachedProcs = 0;
20018 mNumCachedHiddenProcs = 0;
20020 // First update the OOM adjustment for each of the
20021 // application processes based on their current state.
20022 int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20023 int nextCachedAdj = curCachedAdj+1;
20024 int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20025 int nextEmptyAdj = curEmptyAdj+2;
20026 for (int i=N-1; i>=0; i--) {
20027 ProcessRecord app = mLruProcesses.get(i);
20028 if (!app.killedByAm && app.thread != null) {
20029 app.procStateChanged = false;
20030 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20032 // If we haven't yet assigned the final cached adj
20033 // to the process, do that now.
20034 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20035 switch (app.curProcState) {
20036 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20037 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20038 // This process is a cached process holding activities...
20039 // assign it the next cached value for that type, and then
20040 // step that cached level.
20041 app.curRawAdj = curCachedAdj;
20042 app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20043 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20044 + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20046 if (curCachedAdj != nextCachedAdj) {
20048 if (stepCached >= cachedFactor) {
20050 curCachedAdj = nextCachedAdj;
20051 nextCachedAdj += 2;
20052 if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20053 nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20059 // For everything else, assign next empty cached process
20060 // level and bump that up. Note that this means that
20061 // long-running services that have dropped down to the
20062 // cached level will be treated as empty (since their process
20063 // state is still as a service), which is what we want.
20064 app.curRawAdj = curEmptyAdj;
20065 app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20066 if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20067 + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20069 if (curEmptyAdj != nextEmptyAdj) {
20071 if (stepEmpty >= emptyFactor) {
20073 curEmptyAdj = nextEmptyAdj;
20075 if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20076 nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20084 applyOomAdjLocked(app, true, now, nowElapsed);
20086 // Count the number of process types.
20087 switch (app.curProcState) {
20088 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20089 case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20090 mNumCachedHiddenProcs++;
20092 if (numCached > cachedProcessLimit) {
20093 app.kill("cached #" + numCached, true);
20096 case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20097 if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20098 && app.lastActivityTime < oldTime) {
20099 app.kill("empty for "
20100 + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20101 / 1000) + "s", true);
20104 if (numEmpty > emptyProcessLimit) {
20105 app.kill("empty #" + numEmpty, DEBUG_PROCESSES);
20110 mNumNonCachedProcs++;
20114 if (app.isolated && app.services.size() <= 0) {
20115 // If this is an isolated process, and there are no
20116 // services running in it, then the process is no longer
20117 // needed. We agressively kill these because we can by
20118 // definition not re-use the same process again, and it is
20119 // good to avoid having whatever code was running in them
20120 // left sitting around after no longer needed.
20121 app.kill("isolated not needed", true);
20123 // Keeping this process, update its uid.
20124 final UidRecord uidRec = app.uidRecord;
20125 if (uidRec != null && uidRec.curProcState > app.curProcState) {
20126 uidRec.curProcState = app.curProcState;
20130 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20131 && !app.killedByAm) {
20137 mNumServiceProcs = mNewNumServiceProcs;
20139 // Now determine the memory trimming level of background processes.
20140 // Unfortunately we need to start at the back of the list to do this
20141 // properly. We only do this if the number of background apps we
20142 // are managing to keep around is less than half the maximum we desire;
20143 // if we are keeping a good number around, we'll let them use whatever
20144 // memory they want.
20145 final int numCachedAndEmpty = numCached + numEmpty;
20147 if (numCached <= ProcessList.TRIM_CACHED_APPS
20148 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
20149 if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
20150 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
20151 } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
20152 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
20154 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
20157 memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
20159 // We always allow the memory level to go up (better). We only allow it to go
20160 // down if we are in a state where that is allowed, *and* the total number of processes
20161 // has gone down since last time.
20162 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
20163 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
20164 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
20165 if (memFactor > mLastMemoryLevel) {
20166 if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
20167 memFactor = mLastMemoryLevel;
20168 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
20171 mLastMemoryLevel = memFactor;
20172 mLastNumProcesses = mLruProcesses.size();
20173 boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleeping(), now);
20174 final int trackerMemFactor = mProcessStats.getMemFactorLocked();
20175 if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
20176 if (mLowRamStartTime == 0) {
20177 mLowRamStartTime = now;
20181 switch (memFactor) {
20182 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
20183 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
20185 case ProcessStats.ADJ_MEM_FACTOR_LOW:
20186 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
20189 fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
20192 int factor = numTrimming/3;
20194 if (mHomeProcess != null) minFactor++;
20195 if (mPreviousProcess != null) minFactor++;
20196 if (factor < minFactor) factor = minFactor;
20197 int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
20198 for (int i=N-1; i>=0; i--) {
20199 ProcessRecord app = mLruProcesses.get(i);
20200 if (allChanged || app.procStateChanged) {
20201 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20202 app.procStateChanged = false;
20204 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20205 && !app.killedByAm) {
20206 if (app.trimMemoryLevel < curLevel && app.thread != null) {
20208 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20209 "Trimming memory of " + app.processName + " to " + curLevel);
20210 app.thread.scheduleTrimMemory(curLevel);
20211 } catch (RemoteException e) {
20214 // For now we won't do this; our memory trimming seems
20215 // to be good enough at this point that destroying
20216 // activities causes more harm than good.
20217 if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
20218 && app != mHomeProcess && app != mPreviousProcess) {
20219 // Need to do this on its own message because the stack may not
20220 // be in a consistent state at this point.
20221 // For these apps we will also finish their activities
20222 // to help them free memory.
20223 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
20227 app.trimMemoryLevel = curLevel;
20229 if (step >= factor) {
20231 switch (curLevel) {
20232 case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
20233 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
20235 case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
20236 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20240 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
20241 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
20242 && app.thread != null) {
20244 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20245 "Trimming memory of heavy-weight " + app.processName
20246 + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20247 app.thread.scheduleTrimMemory(
20248 ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
20249 } catch (RemoteException e) {
20252 app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
20254 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20255 || app.systemNoUi) && app.pendingUiClean) {
20256 // If this application is now in the background and it
20257 // had done UI, then give it the special trim level to
20258 // have it free UI resources.
20259 final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
20260 if (app.trimMemoryLevel < level && app.thread != null) {
20262 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20263 "Trimming memory of bg-ui " + app.processName
20265 app.thread.scheduleTrimMemory(level);
20266 } catch (RemoteException e) {
20269 app.pendingUiClean = false;
20271 if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
20273 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20274 "Trimming memory of fg " + app.processName
20275 + " to " + fgTrimLevel);
20276 app.thread.scheduleTrimMemory(fgTrimLevel);
20277 } catch (RemoteException e) {
20280 app.trimMemoryLevel = fgTrimLevel;
20284 if (mLowRamStartTime != 0) {
20285 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
20286 mLowRamStartTime = 0;
20288 for (int i=N-1; i>=0; i--) {
20289 ProcessRecord app = mLruProcesses.get(i);
20290 if (allChanged || app.procStateChanged) {
20291 setProcessTrackerStateLocked(app, trackerMemFactor, now);
20292 app.procStateChanged = false;
20294 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
20295 || app.systemNoUi) && app.pendingUiClean) {
20296 if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
20297 && app.thread != null) {
20299 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20300 "Trimming memory of ui hidden " + app.processName
20301 + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20302 app.thread.scheduleTrimMemory(
20303 ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
20304 } catch (RemoteException e) {
20307 app.pendingUiClean = false;
20309 app.trimMemoryLevel = 0;
20313 if (mAlwaysFinishActivities) {
20314 // Need to do this on its own message because the stack may not
20315 // be in a consistent state at this point.
20316 mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
20320 requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
20323 // Update from any uid changes.
20324 for (int i=mActiveUids.size()-1; i>=0; i--) {
20325 final UidRecord uidRec = mActiveUids.valueAt(i);
20326 int uidChange = UidRecord.CHANGE_PROCSTATE;
20327 if (uidRec.setProcState != uidRec.curProcState) {
20328 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20329 "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
20330 + " to " + uidRec.curProcState);
20331 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
20332 if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
20333 uidRec.lastBackgroundTime = nowElapsed;
20334 if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
20335 // Note: the background settle time is in elapsed realtime, while
20336 // the handler time base is uptime. All this means is that we may
20337 // stop background uids later than we had intended, but that only
20338 // happens because the device was sleeping so we are okay anyway.
20339 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
20344 uidChange = UidRecord.CHANGE_ACTIVE;
20345 uidRec.idle = false;
20347 uidRec.lastBackgroundTime = 0;
20349 uidRec.setProcState = uidRec.curProcState;
20350 enqueueUidChangeLocked(uidRec, -1, uidChange);
20351 mBatteryStatsService.noteUidProcessState(uidRec.uid, uidRec.curProcState);
20355 if (mProcessStats.shouldWriteNowLocked(now)) {
20356 mHandler.post(new Runnable() {
20357 @Override public void run() {
20358 synchronized (ActivityManagerService.this) {
20359 mProcessStats.writeStateAsyncLocked();
20365 if (DEBUG_OOM_ADJ) {
20366 final long duration = SystemClock.uptimeMillis() - now;
20368 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
20369 new RuntimeException("here").fillInStackTrace());
20371 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
20376 final void idleUids() {
20377 synchronized (this) {
20378 final long nowElapsed = SystemClock.elapsedRealtime();
20379 final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
20381 for (int i=mActiveUids.size()-1; i>=0; i--) {
20382 final UidRecord uidRec = mActiveUids.valueAt(i);
20383 final long bgTime = uidRec.lastBackgroundTime;
20384 if (bgTime > 0 && !uidRec.idle) {
20385 if (bgTime <= maxBgTime) {
20386 uidRec.idle = true;
20387 doStopUidLocked(uidRec.uid, uidRec);
20389 if (nextTime == 0 || nextTime > bgTime) {
20395 if (nextTime > 0) {
20396 mHandler.removeMessages(IDLE_UIDS_MSG);
20397 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
20398 nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
20403 final void runInBackgroundDisabled(int uid) {
20404 synchronized (this) {
20405 UidRecord uidRec = mActiveUids.get(uid);
20406 if (uidRec != null) {
20407 // This uid is actually running... should it be considered background now?
20409 doStopUidLocked(uidRec.uid, uidRec);
20412 // This uid isn't actually running... still send a report about it being "stopped".
20413 doStopUidLocked(uid, null);
20418 final void doStopUidLocked(int uid, final UidRecord uidRec) {
20419 mServices.stopInBackgroundLocked(uid);
20420 enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
20423 final void trimApplications() {
20424 synchronized (this) {
20427 // First remove any unused application processes whose package
20428 // has been removed.
20429 for (i=mRemovedProcesses.size()-1; i>=0; i--) {
20430 final ProcessRecord app = mRemovedProcesses.get(i);
20431 if (app.activities.size() == 0
20432 && app.curReceiver == null && app.services.size() == 0) {
20434 TAG, "Exiting empty application process "
20435 + app.processName + " ("
20436 + (app.thread != null ? app.thread.asBinder() : null)
20438 if (app.pid > 0 && app.pid != MY_PID) {
20439 app.kill("empty", false);
20442 app.thread.scheduleExit();
20443 } catch (Exception e) {
20444 // Ignore exceptions.
20447 cleanUpApplicationRecordLocked(app, false, true, -1);
20448 mRemovedProcesses.remove(i);
20450 if (app.persistent) {
20451 addAppLocked(app.info, false, null /* ABI override */);
20456 // Now update the oom adj for all processes.
20457 updateOomAdjLocked();
20461 /** This method sends the specified signal to each of the persistent apps */
20462 public void signalPersistentProcesses(int sig) throws RemoteException {
20463 if (sig != Process.SIGNAL_USR1) {
20464 throw new SecurityException("Only SIGNAL_USR1 is allowed");
20467 synchronized (this) {
20468 if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
20469 != PackageManager.PERMISSION_GRANTED) {
20470 throw new SecurityException("Requires permission "
20471 + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
20474 for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
20475 ProcessRecord r = mLruProcesses.get(i);
20476 if (r.thread != null && r.persistent) {
20477 Process.sendSignal(r.pid, sig);
20483 private void stopProfilerLocked(ProcessRecord proc, int profileType) {
20484 if (proc == null || proc == mProfileProc) {
20485 proc = mProfileProc;
20486 profileType = mProfileType;
20487 clearProfilerLocked();
20489 if (proc == null) {
20493 proc.thread.profilerControl(false, null, profileType);
20494 } catch (RemoteException e) {
20495 throw new IllegalStateException("Process disappeared");
20499 private void clearProfilerLocked() {
20500 if (mProfileFd != null) {
20502 mProfileFd.close();
20503 } catch (IOException e) {
20506 mProfileApp = null;
20507 mProfileProc = null;
20508 mProfileFile = null;
20510 mAutoStopProfiler = false;
20511 mSamplingInterval = 0;
20514 public boolean profileControl(String process, int userId, boolean start,
20515 ProfilerInfo profilerInfo, int profileType) throws RemoteException {
20518 synchronized (this) {
20519 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20520 // its own permission.
20521 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20522 != PackageManager.PERMISSION_GRANTED) {
20523 throw new SecurityException("Requires permission "
20524 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20527 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
20528 throw new IllegalArgumentException("null profile info or fd");
20531 ProcessRecord proc = null;
20532 if (process != null) {
20533 proc = findProcessLocked(process, userId, "profileControl");
20536 if (start && (proc == null || proc.thread == null)) {
20537 throw new IllegalArgumentException("Unknown process: " + process);
20541 stopProfilerLocked(null, 0);
20542 setProfileApp(proc.info, proc.processName, profilerInfo);
20543 mProfileProc = proc;
20544 mProfileType = profileType;
20545 ParcelFileDescriptor fd = profilerInfo.profileFd;
20548 } catch (IOException e) {
20551 profilerInfo.profileFd = fd;
20552 proc.thread.profilerControl(start, profilerInfo, profileType);
20556 stopProfilerLocked(proc, profileType);
20557 if (profilerInfo != null && profilerInfo.profileFd != null) {
20559 profilerInfo.profileFd.close();
20560 } catch (IOException e) {
20567 } catch (RemoteException e) {
20568 throw new IllegalStateException("Process disappeared");
20570 if (profilerInfo != null && profilerInfo.profileFd != null) {
20572 profilerInfo.profileFd.close();
20573 } catch (IOException e) {
20579 private ProcessRecord findProcessLocked(String process, int userId, String callName) {
20580 userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
20581 userId, true, ALLOW_FULL_ONLY, callName, null);
20582 ProcessRecord proc = null;
20584 int pid = Integer.parseInt(process);
20585 synchronized (mPidsSelfLocked) {
20586 proc = mPidsSelfLocked.get(pid);
20588 } catch (NumberFormatException e) {
20591 if (proc == null) {
20592 ArrayMap<String, SparseArray<ProcessRecord>> all
20593 = mProcessNames.getMap();
20594 SparseArray<ProcessRecord> procs = all.get(process);
20595 if (procs != null && procs.size() > 0) {
20596 proc = procs.valueAt(0);
20597 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
20598 for (int i=1; i<procs.size(); i++) {
20599 ProcessRecord thisProc = procs.valueAt(i);
20600 if (thisProc.userId == userId) {
20612 public boolean dumpHeap(String process, int userId, boolean managed,
20613 String path, ParcelFileDescriptor fd) throws RemoteException {
20616 synchronized (this) {
20617 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
20618 // its own permission (same as profileControl).
20619 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20620 != PackageManager.PERMISSION_GRANTED) {
20621 throw new SecurityException("Requires permission "
20622 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20626 throw new IllegalArgumentException("null fd");
20629 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
20630 if (proc == null || proc.thread == null) {
20631 throw new IllegalArgumentException("Unknown process: " + process);
20634 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20635 if (!isDebuggable) {
20636 if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20637 throw new SecurityException("Process not debuggable: " + proc);
20641 proc.thread.dumpHeap(managed, path, fd);
20645 } catch (RemoteException e) {
20646 throw new IllegalStateException("Process disappeared");
20651 } catch (IOException e) {
20658 public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
20659 String reportPackage) {
20660 if (processName != null) {
20661 enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
20662 "setDumpHeapDebugLimit()");
20664 synchronized (mPidsSelfLocked) {
20665 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
20666 if (proc == null) {
20667 throw new SecurityException("No process found for calling pid "
20668 + Binder.getCallingPid());
20670 if (!Build.IS_DEBUGGABLE
20671 && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20672 throw new SecurityException("Not running a debuggable build");
20674 processName = proc.processName;
20676 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
20677 throw new SecurityException("Package " + reportPackage + " is not running in "
20682 synchronized (this) {
20683 if (maxMemSize > 0) {
20684 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
20687 mMemWatchProcesses.remove(processName, uid);
20689 mMemWatchProcesses.getMap().remove(processName);
20696 public void dumpHeapFinished(String path) {
20697 synchronized (this) {
20698 if (Binder.getCallingPid() != mMemWatchDumpPid) {
20699 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
20700 + " does not match last pid " + mMemWatchDumpPid);
20703 if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
20704 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
20705 + " does not match last path " + mMemWatchDumpFile);
20708 if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
20709 mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
20713 /** In this method we try to acquire our lock to make sure that we have not deadlocked */
20714 public void monitor() {
20715 synchronized (this) { }
20718 void onCoreSettingsChange(Bundle settings) {
20719 for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20720 ProcessRecord processRecord = mLruProcesses.get(i);
20722 if (processRecord.thread != null) {
20723 processRecord.thread.setCoreSettings(settings);
20725 } catch (RemoteException re) {
20731 // Multi-user methods
20734 * Start user, if its not already running, but don't bring it to foreground.
20737 public boolean startUserInBackground(final int userId) {
20738 return mUserController.startUser(userId, /* foreground */ false);
20742 public boolean unlockUser(int userId, byte[] token, byte[] secret) {
20743 return mUserController.unlockUser(userId, token, secret);
20747 public boolean switchUser(final int targetUserId) {
20748 enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
20749 UserInfo currentUserInfo;
20750 UserInfo targetUserInfo;
20751 synchronized (this) {
20752 int currentUserId = mUserController.getCurrentUserIdLocked();
20753 currentUserInfo = mUserController.getUserInfo(currentUserId);
20754 targetUserInfo = mUserController.getUserInfo(targetUserId);
20755 if (targetUserInfo == null) {
20756 Slog.w(TAG, "No user info for user #" + targetUserId);
20759 if (!targetUserInfo.supportsSwitchTo()) {
20760 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
20763 if (targetUserInfo.isManagedProfile()) {
20764 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
20767 mUserController.setTargetUserIdLocked(targetUserId);
20769 Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
20770 mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
20771 mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
20775 void scheduleStartProfilesLocked() {
20776 if (!mHandler.hasMessages(START_PROFILES_MSG)) {
20777 mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
20778 DateUtils.SECOND_IN_MILLIS);
20783 public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
20784 return mUserController.stopUser(userId, force, callback);
20788 public UserInfo getCurrentUser() {
20789 return mUserController.getCurrentUser();
20793 public boolean isUserRunning(int userId, int flags) {
20794 if (userId != UserHandle.getCallingUserId() && checkCallingPermission(
20795 INTERACT_ACROSS_USERS) != PackageManager.PERMISSION_GRANTED) {
20796 String msg = "Permission Denial: isUserRunning() from pid="
20797 + Binder.getCallingPid()
20798 + ", uid=" + Binder.getCallingUid()
20799 + " requires " + INTERACT_ACROSS_USERS;
20801 throw new SecurityException(msg);
20803 synchronized (this) {
20804 return mUserController.isUserRunningLocked(userId, flags);
20809 public int[] getRunningUserIds() {
20810 if (checkCallingPermission(INTERACT_ACROSS_USERS)
20811 != PackageManager.PERMISSION_GRANTED) {
20812 String msg = "Permission Denial: isUserRunning() from pid="
20813 + Binder.getCallingPid()
20814 + ", uid=" + Binder.getCallingUid()
20815 + " requires " + INTERACT_ACROSS_USERS;
20817 throw new SecurityException(msg);
20819 synchronized (this) {
20820 return mUserController.getStartedUserArrayLocked();
20825 public void registerUserSwitchObserver(IUserSwitchObserver observer) {
20826 mUserController.registerUserSwitchObserver(observer);
20830 public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
20831 mUserController.unregisterUserSwitchObserver(observer);
20834 ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
20835 if (info == null) return null;
20836 ApplicationInfo newInfo = new ApplicationInfo(info);
20837 newInfo.initForUser(userId);
20841 public boolean isUserStopped(int userId) {
20842 synchronized (this) {
20843 return mUserController.getStartedUserStateLocked(userId) == null;
20847 ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
20849 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
20853 ActivityInfo info = new ActivityInfo(aInfo);
20854 info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
20858 private boolean processSanityChecksLocked(ProcessRecord process) {
20859 if (process == null || process.thread == null) {
20863 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20864 if (!isDebuggable) {
20865 if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
20873 public boolean startBinderTracking() throws RemoteException {
20874 synchronized (this) {
20875 mBinderTransactionTrackingEnabled = true;
20876 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20877 // permission (same as profileControl).
20878 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20879 != PackageManager.PERMISSION_GRANTED) {
20880 throw new SecurityException("Requires permission "
20881 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20884 for (int i = 0; i < mLruProcesses.size(); i++) {
20885 ProcessRecord process = mLruProcesses.get(i);
20886 if (!processSanityChecksLocked(process)) {
20890 process.thread.startBinderTracking();
20891 } catch (RemoteException e) {
20892 Log.v(TAG, "Process disappared");
20899 public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
20901 synchronized (this) {
20902 mBinderTransactionTrackingEnabled = false;
20903 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
20904 // permission (same as profileControl).
20905 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
20906 != PackageManager.PERMISSION_GRANTED) {
20907 throw new SecurityException("Requires permission "
20908 + android.Manifest.permission.SET_ACTIVITY_WATCHER);
20912 throw new IllegalArgumentException("null fd");
20915 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
20916 pw.println("Binder transaction traces for all processes.\n");
20917 for (ProcessRecord process : mLruProcesses) {
20918 if (!processSanityChecksLocked(process)) {
20922 pw.println("Traces for process: " + process.processName);
20925 TransferPipe tp = new TransferPipe();
20927 process.thread.stopBinderTrackingAndDump(
20928 tp.getWriteFd().getFileDescriptor());
20929 tp.go(fd.getFileDescriptor());
20933 } catch (IOException e) {
20934 pw.println("Failure while dumping IPC traces from " + process +
20935 ". Exception: " + e);
20937 } catch (RemoteException e) {
20938 pw.println("Got a RemoteException while dumping IPC traces from " +
20939 process + ". Exception: " + e);
20950 } catch (IOException e) {
20956 private final class LocalService extends ActivityManagerInternal {
20958 public void onWakefulnessChanged(int wakefulness) {
20959 ActivityManagerService.this.onWakefulnessChanged(wakefulness);
20963 public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
20964 String processName, String abiOverride, int uid, Runnable crashHandler) {
20965 return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
20966 processName, abiOverride, uid, crashHandler);
20970 public SleepToken acquireSleepToken(String tag) {
20971 Preconditions.checkNotNull(tag);
20973 synchronized (ActivityManagerService.this) {
20974 SleepTokenImpl token = new SleepTokenImpl(tag);
20975 mSleepTokens.add(token);
20976 updateSleepIfNeededLocked();
20982 public ComponentName getHomeActivityForUser(int userId) {
20983 synchronized (ActivityManagerService.this) {
20984 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
20985 return homeActivity == null ? null : homeActivity.realActivity;
20990 public void onUserRemoved(int userId) {
20991 synchronized (ActivityManagerService.this) {
20992 ActivityManagerService.this.onUserStoppedLocked(userId);
20997 public void onLocalVoiceInteractionStarted(IBinder activity,
20998 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
20999 synchronized (ActivityManagerService.this) {
21000 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21001 voiceSession, voiceInteractor);
21006 public void notifyStartingWindowDrawn() {
21007 synchronized (ActivityManagerService.this) {
21008 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21013 public void notifyAppTransitionStarting(int reason) {
21014 synchronized (ActivityManagerService.this) {
21015 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21020 private final class SleepTokenImpl extends SleepToken {
21021 private final String mTag;
21022 private final long mAcquireTime;
21024 public SleepTokenImpl(String tag) {
21026 mAcquireTime = SystemClock.uptimeMillis();
21030 public void release() {
21031 synchronized (ActivityManagerService.this) {
21032 if (mSleepTokens.remove(this)) {
21033 updateSleepIfNeededLocked();
21039 public String toString() {
21040 return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
21045 * An implementation of IAppTask, that allows an app to manage its own tasks via
21046 * {@link android.app.ActivityManager.AppTask}. We keep track of the callingUid to ensure that
21047 * only the process that calls getAppTasks() can call the AppTask methods.
21049 class AppTaskImpl extends IAppTask.Stub {
21050 private int mTaskId;
21051 private int mCallingUid;
21053 public AppTaskImpl(int taskId, int callingUid) {
21055 mCallingUid = callingUid;
21058 private void checkCaller() {
21059 if (mCallingUid != Binder.getCallingUid()) {
21060 throw new SecurityException("Caller " + mCallingUid
21061 + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
21066 public void finishAndRemoveTask() {
21069 synchronized (ActivityManagerService.this) {
21070 long origId = Binder.clearCallingIdentity();
21072 // We remove the task from recents to preserve backwards
21073 if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
21074 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21077 Binder.restoreCallingIdentity(origId);
21083 public ActivityManager.RecentTaskInfo getTaskInfo() {
21086 synchronized (ActivityManagerService.this) {
21087 long origId = Binder.clearCallingIdentity();
21089 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21091 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21093 return createRecentTaskInfoFromTaskRecord(tr);
21095 Binder.restoreCallingIdentity(origId);
21101 public void moveToFront() {
21103 // Will bring task to front if it already has a root activity.
21104 final long origId = Binder.clearCallingIdentity();
21106 startActivityFromRecentsInner(mTaskId, null);
21108 Binder.restoreCallingIdentity(origId);
21113 public int startActivity(IBinder whoThread, String callingPackage,
21114 Intent intent, String resolvedType, Bundle bOptions) {
21117 int callingUser = UserHandle.getCallingUserId();
21119 IApplicationThread appThread;
21120 synchronized (ActivityManagerService.this) {
21121 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21123 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21125 appThread = ApplicationThreadNative.asInterface(whoThread);
21126 if (appThread == null) {
21127 throw new IllegalArgumentException("Bad app thread " + appThread);
21130 return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
21131 resolvedType, null, null, null, null, 0, 0, null, null,
21132 null, bOptions, false, callingUser, null, tr);
21136 public void setExcludeFromRecents(boolean exclude) {
21139 synchronized (ActivityManagerService.this) {
21140 long origId = Binder.clearCallingIdentity();
21142 TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
21144 throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
21146 Intent intent = tr.getBaseIntent();
21148 intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21150 intent.setFlags(intent.getFlags()
21151 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
21154 Binder.restoreCallingIdentity(origId);
21161 * Kill processes for the user with id userId and that depend on the package named packageName
21164 public void killPackageDependents(String packageName, int userId) {
21165 enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
21166 if (packageName == null) {
21167 throw new NullPointerException(
21168 "Cannot kill the dependents of a package without its name.");
21171 long callingId = Binder.clearCallingIdentity();
21172 IPackageManager pm = AppGlobals.getPackageManager();
21175 pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
21176 } catch (RemoteException e) {
21178 if (userId != UserHandle.USER_ALL && pkgUid == -1) {
21179 throw new IllegalArgumentException(
21180 "Cannot kill dependents of non-existing package " + packageName);
21183 synchronized(this) {
21184 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
21185 ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
21186 "dep: " + packageName);
21189 Binder.restoreCallingIdentity(callingId);