• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2006-2008 The Android Open Source Project
3  *
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
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 
17 package com.android.server.am;
18 
19 import com.android.internal.telephony.TelephonyIntents;
20 import com.google.android.collect.Lists;
21 import com.google.android.collect.Maps;
22 import com.android.internal.R;
23 import com.android.internal.annotations.GuardedBy;
24 import com.android.internal.app.AssistUtils;
25 import com.android.internal.app.DumpHeapActivity;
26 import com.android.internal.app.IAppOpsCallback;
27 import com.android.internal.app.IAppOpsService;
28 import com.android.internal.app.IVoiceInteractor;
29 import com.android.internal.app.ProcessMap;
30 import com.android.internal.app.SystemUserHomeActivity;
31 import com.android.internal.app.procstats.ProcessStats;
32 import com.android.internal.os.BackgroundThread;
33 import com.android.internal.os.BatteryStatsImpl;
34 import com.android.internal.os.IResultReceiver;
35 import com.android.internal.os.ProcessCpuTracker;
36 import com.android.internal.os.TransferPipe;
37 import com.android.internal.os.Zygote;
38 import com.android.internal.os.InstallerConnection.InstallerException;
39 import com.android.internal.util.ArrayUtils;
40 import com.android.internal.util.FastPrintWriter;
41 import com.android.internal.util.FastXmlSerializer;
42 import com.android.internal.util.MemInfoReader;
43 import com.android.internal.util.Preconditions;
44 import com.android.server.AppOpsService;
45 import com.android.server.AttributeCache;
46 import com.android.server.DeviceIdleController;
47 import com.android.server.IntentResolver;
48 import com.android.server.LocalServices;
49 import com.android.server.LockGuard;
50 import com.android.server.ServiceThread;
51 import com.android.server.SystemService;
52 import com.android.server.SystemServiceManager;
53 import com.android.server.Watchdog;
54 import com.android.server.am.ActivityStack.ActivityState;
55 import com.android.server.firewall.IntentFirewall;
56 import com.android.server.pm.Installer;
57 import com.android.server.statusbar.StatusBarManagerInternal;
58 import com.android.server.vr.VrManagerInternal;
59 import com.android.server.wm.WindowManagerService;
60 
61 import org.xmlpull.v1.XmlPullParser;
62 import org.xmlpull.v1.XmlPullParserException;
63 import org.xmlpull.v1.XmlSerializer;
64 
65 import android.Manifest;
66 import android.Manifest.permission;
67 import android.annotation.NonNull;
68 import android.annotation.UserIdInt;
69 import android.app.Activity;
70 import android.app.ActivityManager;
71 import android.app.ActivityManager.RunningTaskInfo;
72 import android.app.ActivityManager.StackId;
73 import android.app.ActivityManager.StackInfo;
74 import android.app.ActivityManager.TaskThumbnailInfo;
75 import android.app.ActivityManagerInternal;
76 import android.app.ActivityManagerInternal.SleepToken;
77 import android.app.ActivityManagerNative;
78 import android.app.ActivityOptions;
79 import android.app.ActivityThread;
80 import android.app.AlertDialog;
81 import android.app.AppGlobals;
82 import android.app.AppOpsManager;
83 import android.app.ApplicationErrorReport;
84 import android.app.ApplicationThreadNative;
85 import android.app.BroadcastOptions;
86 import android.app.Dialog;
87 import android.app.IActivityContainer;
88 import android.app.IActivityContainerCallback;
89 import android.app.IActivityController;
90 import android.app.IAppTask;
91 import android.app.IApplicationThread;
92 import android.app.IInstrumentationWatcher;
93 import android.app.INotificationManager;
94 import android.app.IProcessObserver;
95 import android.app.IServiceConnection;
96 import android.app.IStopUserCallback;
97 import android.app.ITaskStackListener;
98 import android.app.IUiAutomationConnection;
99 import android.app.IUidObserver;
100 import android.app.IUserSwitchObserver;
101 import android.app.Instrumentation;
102 import android.app.Notification;
103 import android.app.NotificationManager;
104 import android.app.PendingIntent;
105 import android.app.ProfilerInfo;
106 import android.app.admin.DevicePolicyManager;
107 import android.app.assist.AssistContent;
108 import android.app.assist.AssistStructure;
109 import android.app.backup.IBackupManager;
110 import android.app.usage.UsageEvents;
111 import android.app.usage.UsageStatsManagerInternal;
112 import android.appwidget.AppWidgetManager;
113 import android.content.ActivityNotFoundException;
114 import android.content.BroadcastReceiver;
115 import android.content.ClipData;
116 import android.content.ComponentCallbacks2;
117 import android.content.ComponentName;
118 import android.content.ContentProvider;
119 import android.content.ContentResolver;
120 import android.content.Context;
121 import android.content.DialogInterface;
122 import android.content.IContentProvider;
123 import android.content.IIntentReceiver;
124 import android.content.IIntentSender;
125 import android.content.Intent;
126 import android.content.IntentFilter;
127 import android.content.IntentSender;
128 import android.content.pm.ActivityInfo;
129 import android.content.pm.ApplicationInfo;
130 import android.content.pm.ConfigurationInfo;
131 import android.content.pm.IPackageDataObserver;
132 import android.content.pm.IPackageManager;
133 import android.content.pm.InstrumentationInfo;
134 import android.content.pm.PackageInfo;
135 import android.content.pm.PackageManager;
136 import android.content.pm.PackageManager.NameNotFoundException;
137 import android.content.pm.PackageManagerInternal;
138 import android.content.pm.ParceledListSlice;
139 import android.content.pm.PathPermission;
140 import android.content.pm.PermissionInfo;
141 import android.content.pm.ProviderInfo;
142 import android.content.pm.ResolveInfo;
143 import android.content.pm.ServiceInfo;
144 import android.content.pm.UserInfo;
145 import android.content.res.CompatibilityInfo;
146 import android.content.res.Configuration;
147 import android.content.res.Resources;
148 import android.database.ContentObserver;
149 import android.graphics.Bitmap;
150 import android.graphics.Point;
151 import android.graphics.Rect;
152 import android.location.LocationManager;
153 import android.net.Proxy;
154 import android.net.ProxyInfo;
155 import android.net.Uri;
156 import android.os.BatteryStats;
157 import android.os.Binder;
158 import android.os.Build;
159 import android.os.Bundle;
160 import android.os.Debug;
161 import android.os.DropBoxManager;
162 import android.os.Environment;
163 import android.os.FactoryTest;
164 import android.os.FileObserver;
165 import android.os.FileUtils;
166 import android.os.Handler;
167 import android.os.IBinder;
168 import android.os.IPermissionController;
169 import android.os.IProcessInfoService;
170 import android.os.IProgressListener;
171 import android.os.LocaleList;
172 import android.os.Looper;
173 import android.os.Message;
174 import android.os.Parcel;
175 import android.os.ParcelFileDescriptor;
176 import android.os.PersistableBundle;
177 import android.os.PowerManager;
178 import android.os.PowerManagerInternal;
179 import android.os.Process;
180 import android.os.RemoteCallbackList;
181 import android.os.RemoteException;
182 import android.os.ResultReceiver;
183 import android.os.ServiceManager;
184 import android.os.StrictMode;
185 import android.os.SystemClock;
186 import android.os.SystemProperties;
187 import android.os.Trace;
188 import android.os.TransactionTooLargeException;
189 import android.os.UpdateLock;
190 import android.os.UserHandle;
191 import android.os.UserManager;
192 import android.os.WorkSource;
193 import android.os.storage.IMountService;
194 import android.os.storage.MountServiceInternal;
195 import android.os.storage.StorageManager;
196 import android.provider.Settings;
197 import android.service.voice.IVoiceInteractionSession;
198 import android.service.voice.VoiceInteractionManagerInternal;
199 import android.service.voice.VoiceInteractionSession;
200 import android.telecom.TelecomManager;
201 import android.text.format.DateUtils;
202 import android.text.format.Time;
203 import android.text.style.SuggestionSpan;
204 import android.util.ArrayMap;
205 import android.util.ArraySet;
206 import android.util.AtomicFile;
207 import android.util.DebugUtils;
208 import android.util.DisplayMetrics;
209 import android.util.EventLog;
210 import android.util.Log;
211 import android.util.Pair;
212 import android.util.PrintWriterPrinter;
213 import android.util.Slog;
214 import android.util.SparseArray;
215 import android.util.TimeUtils;
216 import android.util.Xml;
217 import android.view.Display;
218 import android.view.Gravity;
219 import android.view.LayoutInflater;
220 import android.view.View;
221 import android.view.WindowManager;
222 
223 import java.io.File;
224 import java.io.FileDescriptor;
225 import java.io.FileInputStream;
226 import java.io.FileNotFoundException;
227 import java.io.FileOutputStream;
228 import java.io.IOException;
229 import java.io.InputStreamReader;
230 import java.io.PrintWriter;
231 import java.io.StringWriter;
232 import java.lang.ref.WeakReference;
233 import java.nio.charset.StandardCharsets;
234 import java.util.ArrayList;
235 import java.util.Arrays;
236 import java.util.Collections;
237 import java.util.Comparator;
238 import java.util.HashMap;
239 import java.util.HashSet;
240 import java.util.Iterator;
241 import java.util.List;
242 import java.util.Locale;
243 import java.util.Map;
244 import java.util.Objects;
245 import java.util.Set;
246 import java.util.concurrent.atomic.AtomicBoolean;
247 import java.util.concurrent.atomic.AtomicLong;
248 
249 import dalvik.system.VMRuntime;
250 
251 import libcore.io.IoUtils;
252 import libcore.util.EmptyArray;
253 
254 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
256 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
257 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
258 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
259 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
260 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
261 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
262 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
264 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
265 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
266 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
267 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
268 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
269 import static android.content.pm.PackageManager.GET_PROVIDERS;
270 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
271 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
273 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
274 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
275 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
276 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
277 import static android.os.Process.PROC_CHAR;
278 import static android.os.Process.PROC_OUT_LONG;
279 import static android.os.Process.PROC_PARENS;
280 import static android.os.Process.PROC_SPACE_TERM;
281 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
282 import static android.provider.Settings.Global.DEBUG_APP;
283 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
284 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
286 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
287 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
288 import static android.provider.Settings.System.FONT_SCALE;
289 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
290 import static com.android.internal.util.XmlUtils.readIntAttribute;
291 import static com.android.internal.util.XmlUtils.readLongAttribute;
292 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
293 import static com.android.internal.util.XmlUtils.writeIntAttribute;
294 import static com.android.internal.util.XmlUtils.writeLongAttribute;
295 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
328 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
352 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
354 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
355 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
356 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
357 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
358 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
359 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
360 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
361 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
362 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
365 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
367 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
370 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
371 import static org.xmlpull.v1.XmlPullParser.START_TAG;
372 
373 public final class ActivityManagerService extends ActivityManagerNative
374         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
375 
376     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
377     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
378     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
379     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
380     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
381     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
382     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
383     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
384     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
385     private static final String TAG_LRU = TAG + POSTFIX_LRU;
386     private static final String TAG_MU = TAG + POSTFIX_MU;
387     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
388     private static final String TAG_POWER = TAG + POSTFIX_POWER;
389     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
390     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
391     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
392     private static final String TAG_PSS = TAG + POSTFIX_PSS;
393     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
394     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
395     private static final String TAG_STACK = TAG + POSTFIX_STACK;
396     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
397     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
398     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
399     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
400     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
401 
402     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
403     // here so that while the job scheduler can depend on AMS, the other way around
404     // need not be the case.
405     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
406 
407     /** Control over CPU and battery monitoring */
408     // write battery stats every 30 minutes.
409     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
410     static final boolean MONITOR_CPU_USAGE = true;
411     // don't sample cpu less than every 5 seconds.
412     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
413     // wait possibly forever for next cpu sample.
414     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
415     static final boolean MONITOR_THREAD_CPU_USAGE = false;
416 
417     // The flags that are set for all calls we make to the package manager.
418     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
419 
420     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
421 
422     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
423 
424     // Amount of time after a call to stopAppSwitches() during which we will
425     // prevent further untrusted switches from happening.
426     static final long APP_SWITCH_DELAY_TIME = 5*1000;
427 
428     // How long we wait for a launched process to attach to the activity manager
429     // before we decide it's never going to come up for real.
430     static final int PROC_START_TIMEOUT = 10*1000;
431     // How long we wait for an attached process to publish its content providers
432     // before we decide it must be hung.
433     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
434 
435     // How long we will retain processes hosting content providers in the "last activity"
436     // state before allowing them to drop down to the regular cached LRU list.  This is
437     // to avoid thrashing of provider processes under low memory situations.
438     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
439 
440     // How long we wait for a launched process to attach to the activity manager
441     // before we decide it's never going to come up for real, when the process was
442     // started with a wrapper for instrumentation (such as Valgrind) because it
443     // could take much longer than usual.
444     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
445 
446     // How long to wait after going idle before forcing apps to GC.
447     static final int GC_TIMEOUT = 5*1000;
448 
449     // The minimum amount of time between successive GC requests for a process.
450     static final int GC_MIN_INTERVAL = 60*1000;
451 
452     // The minimum amount of time between successive PSS requests for a process.
453     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
454 
455     // The minimum amount of time between successive PSS requests for a process
456     // when the request is due to the memory state being lowered.
457     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
458 
459     // The rate at which we check for apps using excessive power -- 15 mins.
460     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
461 
462     // The minimum sample duration we will allow before deciding we have
463     // enough data on wake locks to start killing things.
464     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
465 
466     // The minimum sample duration we will allow before deciding we have
467     // enough data on CPU usage to start killing things.
468     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
469 
470     // How long we allow a receiver to run before giving up on it.
471     static final int BROADCAST_FG_TIMEOUT = 10*1000;
472     static final int BROADCAST_BG_TIMEOUT = 60*1000;
473 
474     // How long we wait until we timeout on key dispatching.
475     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
476 
477     // How long we wait until we timeout on key dispatching during instrumentation.
478     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
479 
480     // This is the amount of time an app needs to be running a foreground service before
481     // we will consider it to be doing interaction for usage stats.
482     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
483 
484     // Maximum amount of time we will allow to elapse before re-reporting usage stats
485     // interaction with foreground processes.
486     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
487 
488     // This is the amount of time we allow an app to settle after it goes into the background,
489     // before we start restricting what it can do.
490     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
491 
492     // How long to wait in getAssistContextExtras for the activity and foreground services
493     // to respond with the result.
494     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
495 
496     // How long top wait when going through the modern assist (which doesn't need to block
497     // on getting this result before starting to launch its UI).
498     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
499 
500     // Maximum number of persisted Uri grants a package is allowed
501     static final int MAX_PERSISTED_URI_GRANTS = 128;
502 
503     static final int MY_PID = Process.myPid();
504 
505     static final String[] EMPTY_STRING_ARRAY = new String[0];
506 
507     // How many bytes to write into the dropbox log before truncating
508     static final int DROPBOX_MAX_SIZE = 192 * 1024;
509     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
510     // as one line, but close enough for now.
511     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
512 
513     // Access modes for handleIncomingUser.
514     static final int ALLOW_NON_FULL = 0;
515     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
516     static final int ALLOW_FULL_ONLY = 2;
517 
518     // Delay in notifying task stack change listeners (in millis)
519     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
520 
521     // Necessary ApplicationInfo flags to mark an app as persistent
522     private static final int PERSISTENT_MASK =
523             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
524 
525     // Intent sent when remote bugreport collection has been completed
526     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
527             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
528 
529     // Delay to disable app launch boost
530     static final int APP_BOOST_MESSAGE_DELAY = 3000;
531     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
532     static final int APP_BOOST_TIMEOUT = 2500;
533 
534     // Used to indicate that a task is removed it should also be removed from recents.
535     private static final boolean REMOVE_FROM_RECENTS = true;
536     // Used to indicate that an app transition should be animated.
537     static final boolean ANIMATE = true;
538 
539     // Determines whether to take full screen screenshots
540     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
541     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
542 
nativeMigrateToBoost()543     private static native int nativeMigrateToBoost();
nativeMigrateFromBoost()544     private static native int nativeMigrateFromBoost();
545     private boolean mIsBoosted = false;
546     private long mBoostStartTime = 0;
547 
548     /** All system services */
549     SystemServiceManager mSystemServiceManager;
550 
551     private Installer mInstaller;
552 
553     /** Run all ActivityStacks through this */
554     final ActivityStackSupervisor mStackSupervisor;
555 
556     final ActivityStarter mActivityStarter;
557 
558     /** Task stack change listeners. */
559     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
560             new RemoteCallbackList<ITaskStackListener>();
561 
562     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
563 
564     public IntentFirewall mIntentFirewall;
565 
566     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
567     // default actuion automatically.  Important for devices without direct input
568     // devices.
569     private boolean mShowDialogs = true;
570     private boolean mInVrMode = false;
571 
572     // Whether we should use SCHED_FIFO for UI and RenderThreads.
573     private boolean mUseFifoUiScheduling = false;
574 
575     BroadcastQueue mFgBroadcastQueue;
576     BroadcastQueue mBgBroadcastQueue;
577     // Convenient for easy iteration over the queues. Foreground is first
578     // so that dispatch of foreground broadcasts gets precedence.
579     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
580 
581     BroadcastStats mLastBroadcastStats;
582     BroadcastStats mCurBroadcastStats;
583 
broadcastQueueForIntent(Intent intent)584     BroadcastQueue broadcastQueueForIntent(Intent intent) {
585         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
586         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
587                 "Broadcast intent " + intent + " on "
588                 + (isFg ? "foreground" : "background") + " queue");
589         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
590     }
591 
592     /**
593      * Activity we have told the window manager to have key focus.
594      */
595     ActivityRecord mFocusedActivity = null;
596 
597     /**
598      * User id of the last activity mFocusedActivity was set to.
599      */
600     private int mLastFocusedUserId;
601 
602     /**
603      * If non-null, we are tracking the time the user spends in the currently focused app.
604      */
605     private AppTimeTracker mCurAppTimeTracker;
606 
607     /**
608      * List of intents that were used to start the most recent tasks.
609      */
610     final RecentTasks mRecentTasks;
611 
612     /**
613      * For addAppTask: cached of the last activity component that was added.
614      */
615     ComponentName mLastAddedTaskComponent;
616 
617     /**
618      * For addAppTask: cached of the last activity uid that was added.
619      */
620     int mLastAddedTaskUid;
621 
622     /**
623      * For addAppTask: cached of the last ActivityInfo that was added.
624      */
625     ActivityInfo mLastAddedTaskActivity;
626 
627     /**
628      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
629      */
630     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
631 
632     /**
633      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
634      */
635     String mDeviceOwnerName;
636 
637     final UserController mUserController;
638 
639     final AppErrors mAppErrors;
640 
641     boolean mDoingSetFocusedActivity;
642 
canShowErrorDialogs()643     public boolean canShowErrorDialogs() {
644         return mShowDialogs && !mSleeping && !mShuttingDown;
645     }
646 
647     private static final class PriorityState {
648         // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
649         // the current thread is currently in. When it drops down to zero, we will no longer boost
650         // the thread's priority.
651         private int regionCounter = 0;
652 
653         // The thread's previous priority before boosting.
654         private int prevPriority = Integer.MIN_VALUE;
655     }
656 
657     static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
658         @Override protected PriorityState initialValue() {
659             return new PriorityState();
660         }
661     };
662 
boostPriorityForLockedSection()663     static void boostPriorityForLockedSection() {
664         int tid = Process.myTid();
665         int prevPriority = Process.getThreadPriority(tid);
666         PriorityState state = sThreadPriorityState.get();
667         if (state.regionCounter == 0 && prevPriority > -2) {
668             state.prevPriority = prevPriority;
669             Process.setThreadPriority(tid, -2);
670         }
671         state.regionCounter++;
672     }
673 
resetPriorityAfterLockedSection()674     static void resetPriorityAfterLockedSection() {
675         PriorityState state = sThreadPriorityState.get();
676         state.regionCounter--;
677         if (state.regionCounter == 0 && state.prevPriority > -2) {
678             Process.setThreadPriority(Process.myTid(), state.prevPriority);
679         }
680     }
681 
682     public class PendingAssistExtras extends Binder implements Runnable {
683         public final ActivityRecord activity;
684         public final Bundle extras;
685         public final Intent intent;
686         public final String hint;
687         public final IResultReceiver receiver;
688         public final int userHandle;
689         public boolean haveResult = false;
690         public Bundle result = null;
691         public AssistStructure structure = null;
692         public AssistContent content = null;
693         public Bundle receiverExtras;
694 
PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent, String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle)695         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
696                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
697             activity = _activity;
698             extras = _extras;
699             intent = _intent;
700             hint = _hint;
701             receiver = _receiver;
702             receiverExtras = _receiverExtras;
703             userHandle = _userHandle;
704         }
705         @Override
run()706         public void run() {
707             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
708             synchronized (this) {
709                 haveResult = true;
710                 notifyAll();
711             }
712             pendingAssistExtrasTimedOut(this);
713         }
714     }
715 
716     final ArrayList<PendingAssistExtras> mPendingAssistExtras
717             = new ArrayList<PendingAssistExtras>();
718 
719     /**
720      * Process management.
721      */
722     final ProcessList mProcessList = new ProcessList();
723 
724     /**
725      * All of the applications we currently have running organized by name.
726      * The keys are strings of the application package name (as
727      * returned by the package manager), and the keys are ApplicationRecord
728      * objects.
729      */
730     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
731 
732     /**
733      * Tracking long-term execution of processes to look for abuse and other
734      * bad app behavior.
735      */
736     final ProcessStatsService mProcessStats;
737 
738     /**
739      * The currently running isolated processes.
740      */
741     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
742 
743     /**
744      * Counter for assigning isolated process uids, to avoid frequently reusing the
745      * same ones.
746      */
747     int mNextIsolatedProcessUid = 0;
748 
749     /**
750      * The currently running heavy-weight process, if any.
751      */
752     ProcessRecord mHeavyWeightProcess = null;
753 
754     /**
755      * All of the processes we currently have running organized by pid.
756      * The keys are the pid running the application.
757      *
758      * <p>NOTE: This object is protected by its own lock, NOT the global
759      * activity manager lock!
760      */
761     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
762 
763     /**
764      * All of the processes that have been forced to be foreground.  The key
765      * is the pid of the caller who requested it (we hold a death
766      * link on it).
767      */
768     abstract class ForegroundToken implements IBinder.DeathRecipient {
769         int pid;
770         IBinder token;
771     }
772     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
773 
774     /**
775      * List of records for processes that someone had tried to start before the
776      * system was ready.  We don't start them at that point, but ensure they
777      * are started by the time booting is complete.
778      */
779     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
780 
781     /**
782      * List of persistent applications that are in the process
783      * of being started.
784      */
785     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
786 
787     /**
788      * Processes that are being forcibly torn down.
789      */
790     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
791 
792     /**
793      * List of running applications, sorted by recent usage.
794      * The first entry in the list is the least recently used.
795      */
796     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
797 
798     /**
799      * Where in mLruProcesses that the processes hosting activities start.
800      */
801     int mLruProcessActivityStart = 0;
802 
803     /**
804      * Where in mLruProcesses that the processes hosting services start.
805      * This is after (lower index) than mLruProcessesActivityStart.
806      */
807     int mLruProcessServiceStart = 0;
808 
809     /**
810      * List of processes that should gc as soon as things are idle.
811      */
812     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
813 
814     /**
815      * Processes we want to collect PSS data from.
816      */
817     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
818 
819     private boolean mBinderTransactionTrackingEnabled = false;
820 
821     /**
822      * Last time we requested PSS data of all processes.
823      */
824     long mLastFullPssTime = SystemClock.uptimeMillis();
825 
826     /**
827      * If set, the next time we collect PSS data we should do a full collection
828      * with data from native processes and the kernel.
829      */
830     boolean mFullPssPending = false;
831 
832     /**
833      * This is the process holding what we currently consider to be
834      * the "home" activity.
835      */
836     ProcessRecord mHomeProcess;
837 
838     /**
839      * This is the process holding the activity the user last visited that
840      * is in a different process from the one they are currently in.
841      */
842     ProcessRecord mPreviousProcess;
843 
844     /**
845      * The time at which the previous process was last visible.
846      */
847     long mPreviousProcessVisibleTime;
848 
849     /**
850      * Track all uids that have actively running processes.
851      */
852     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
853 
854     /**
855      * This is for verifying the UID report flow.
856      */
857     static final boolean VALIDATE_UID_STATES = true;
858     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
859 
860     /**
861      * Packages that the user has asked to have run in screen size
862      * compatibility mode instead of filling the screen.
863      */
864     final CompatModePackages mCompatModePackages;
865 
866     /**
867      * Set of IntentSenderRecord objects that are currently active.
868      */
869     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
870             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
871 
872     /**
873      * Fingerprints (hashCode()) of stack traces that we've
874      * already logged DropBox entries for.  Guarded by itself.  If
875      * something (rogue user app) forces this over
876      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
877      */
878     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
879     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
880 
881     /**
882      * Strict Mode background batched logging state.
883      *
884      * The string buffer is guarded by itself, and its lock is also
885      * used to determine if another batched write is already
886      * in-flight.
887      */
888     private final StringBuilder mStrictModeBuffer = new StringBuilder();
889 
890     /**
891      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
892      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
893      */
894     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
895 
896     /**
897      * Resolver for broadcast intents to registered receivers.
898      * Holds BroadcastFilter (subclass of IntentFilter).
899      */
900     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
901             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
902         @Override
903         protected boolean allowFilterResult(
904                 BroadcastFilter filter, List<BroadcastFilter> dest) {
905             IBinder target = filter.receiverList.receiver.asBinder();
906             for (int i = dest.size() - 1; i >= 0; i--) {
907                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
908                     return false;
909                 }
910             }
911             return true;
912         }
913 
914         @Override
915         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
916             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
917                     || userId == filter.owningUserId) {
918                 return super.newResult(filter, match, userId);
919             }
920             return null;
921         }
922 
923         @Override
924         protected BroadcastFilter[] newArray(int size) {
925             return new BroadcastFilter[size];
926         }
927 
928         @Override
929         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
930             return packageName.equals(filter.packageName);
931         }
932     };
933 
934     /**
935      * State of all active sticky broadcasts per user.  Keys are the action of the
936      * sticky Intent, values are an ArrayList of all broadcasted intents with
937      * that action (which should usually be one).  The SparseArray is keyed
938      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
939      * for stickies that are sent to all users.
940      */
941     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
942             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
943 
944     final ActiveServices mServices;
945 
946     final static class Association {
947         final int mSourceUid;
948         final String mSourceProcess;
949         final int mTargetUid;
950         final ComponentName mTargetComponent;
951         final String mTargetProcess;
952 
953         int mCount;
954         long mTime;
955 
956         int mNesting;
957         long mStartTime;
958 
959         // states of the source process when the bind occurred.
960         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
961         long mLastStateUptime;
962         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
963                 - ActivityManager.MIN_PROCESS_STATE+1];
964 
Association(int sourceUid, String sourceProcess, int targetUid, ComponentName targetComponent, String targetProcess)965         Association(int sourceUid, String sourceProcess, int targetUid,
966                 ComponentName targetComponent, String targetProcess) {
967             mSourceUid = sourceUid;
968             mSourceProcess = sourceProcess;
969             mTargetUid = targetUid;
970             mTargetComponent = targetComponent;
971             mTargetProcess = targetProcess;
972         }
973     }
974 
975     /**
976      * When service association tracking is enabled, this is all of the associations we
977      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
978      * -> association data.
979      */
980     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
981             mAssociations = new SparseArray<>();
982     boolean mTrackingAssociations;
983 
984     /**
985      * Backup/restore process management
986      */
987     String mBackupAppName = null;
988     BackupRecord mBackupTarget = null;
989 
990     final ProviderMap mProviderMap;
991 
992     /**
993      * List of content providers who have clients waiting for them.  The
994      * application is currently being launched and the provider will be
995      * removed from this list once it is published.
996      */
997     final ArrayList<ContentProviderRecord> mLaunchingProviders
998             = new ArrayList<ContentProviderRecord>();
999 
1000     /**
1001      * File storing persisted {@link #mGrantedUriPermissions}.
1002      */
1003     private final AtomicFile mGrantFile;
1004 
1005     /** XML constants used in {@link #mGrantFile} */
1006     private static final String TAG_URI_GRANTS = "uri-grants";
1007     private static final String TAG_URI_GRANT = "uri-grant";
1008     private static final String ATTR_USER_HANDLE = "userHandle";
1009     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1010     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1011     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1012     private static final String ATTR_TARGET_PKG = "targetPkg";
1013     private static final String ATTR_URI = "uri";
1014     private static final String ATTR_MODE_FLAGS = "modeFlags";
1015     private static final String ATTR_CREATED_TIME = "createdTime";
1016     private static final String ATTR_PREFIX = "prefix";
1017 
1018     /**
1019      * Global set of specific {@link Uri} permissions that have been granted.
1020      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1021      * to {@link UriPermission#uri} to {@link UriPermission}.
1022      */
1023     @GuardedBy("this")
1024     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1025             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1026 
1027     public static class GrantUri {
1028         public final int sourceUserId;
1029         public final Uri uri;
1030         public boolean prefix;
1031 
GrantUri(int sourceUserId, Uri uri, boolean prefix)1032         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1033             this.sourceUserId = sourceUserId;
1034             this.uri = uri;
1035             this.prefix = prefix;
1036         }
1037 
1038         @Override
hashCode()1039         public int hashCode() {
1040             int hashCode = 1;
1041             hashCode = 31 * hashCode + sourceUserId;
1042             hashCode = 31 * hashCode + uri.hashCode();
1043             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1044             return hashCode;
1045         }
1046 
1047         @Override
equals(Object o)1048         public boolean equals(Object o) {
1049             if (o instanceof GrantUri) {
1050                 GrantUri other = (GrantUri) o;
1051                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1052                         && prefix == other.prefix;
1053             }
1054             return false;
1055         }
1056 
1057         @Override
toString()1058         public String toString() {
1059             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1060             if (prefix) result += " [prefix]";
1061             return result;
1062         }
1063 
toSafeString()1064         public String toSafeString() {
1065             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1066             if (prefix) result += " [prefix]";
1067             return result;
1068         }
1069 
resolve(int defaultSourceUserHandle, Uri uri)1070         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1071             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1072                     ContentProvider.getUriWithoutUserId(uri), false);
1073         }
1074     }
1075 
1076     CoreSettingsObserver mCoreSettingsObserver;
1077 
1078     FontScaleSettingObserver mFontScaleSettingObserver;
1079 
1080     private final class FontScaleSettingObserver extends ContentObserver {
1081         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1082 
FontScaleSettingObserver()1083         public FontScaleSettingObserver() {
1084             super(mHandler);
1085             ContentResolver resolver = mContext.getContentResolver();
1086             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1087         }
1088 
1089         @Override
onChange(boolean selfChange, Uri uri, @UserIdInt int userId)1090         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1091             if (mFontScaleUri.equals(uri)) {
1092                 updateFontScaleIfNeeded(userId);
1093             }
1094         }
1095     }
1096 
1097     /**
1098      * Thread-local storage used to carry caller permissions over through
1099      * indirect content-provider access.
1100      */
1101     private class Identity {
1102         public final IBinder token;
1103         public final int pid;
1104         public final int uid;
1105 
Identity(IBinder _token, int _pid, int _uid)1106         Identity(IBinder _token, int _pid, int _uid) {
1107             token = _token;
1108             pid = _pid;
1109             uid = _uid;
1110         }
1111     }
1112 
1113     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1114 
1115     /**
1116      * All information we have collected about the runtime performance of
1117      * any user id that can impact battery performance.
1118      */
1119     final BatteryStatsService mBatteryStatsService;
1120 
1121     /**
1122      * Information about component usage
1123      */
1124     UsageStatsManagerInternal mUsageStatsService;
1125 
1126     /**
1127      * Access to DeviceIdleController service.
1128      */
1129     DeviceIdleController.LocalService mLocalDeviceIdleController;
1130 
1131     /**
1132      * Information about and control over application operations
1133      */
1134     final AppOpsService mAppOpsService;
1135 
1136     /**
1137      * Current configuration information.  HistoryRecord objects are given
1138      * a reference to this object to indicate which configuration they are
1139      * currently running in, so this object must be kept immutable.
1140      */
1141     Configuration mConfiguration = new Configuration();
1142 
1143     /**
1144      * Current sequencing integer of the configuration, for skipping old
1145      * configurations.
1146      */
1147     int mConfigurationSeq = 0;
1148 
1149     boolean mSuppressResizeConfigChanges = false;
1150 
1151     /**
1152      * Hardware-reported OpenGLES version.
1153      */
1154     final int GL_ES_VERSION;
1155 
1156     /**
1157      * List of initialization arguments to pass to all processes when binding applications to them.
1158      * For example, references to the commonly used services.
1159      */
1160     HashMap<String, IBinder> mAppBindArgs;
1161 
1162     /**
1163      * Temporary to avoid allocations.  Protected by main lock.
1164      */
1165     final StringBuilder mStringBuilder = new StringBuilder(256);
1166 
1167     /**
1168      * Used to control how we initialize the service.
1169      */
1170     ComponentName mTopComponent;
1171     String mTopAction = Intent.ACTION_MAIN;
1172     String mTopData;
1173 
1174     volatile boolean mProcessesReady = false;
1175     volatile boolean mSystemReady = false;
1176     volatile boolean mOnBattery = false;
1177     volatile int mFactoryTest;
1178 
1179     @GuardedBy("this") boolean mBooting = false;
1180     @GuardedBy("this") boolean mCallFinishBooting = false;
1181     @GuardedBy("this") boolean mBootAnimationComplete = false;
1182     @GuardedBy("this") boolean mLaunchWarningShown = false;
1183     @GuardedBy("this") boolean mCheckedForSetup = false;
1184 
1185     Context mContext;
1186 
1187     /**
1188      * The time at which we will allow normal application switches again,
1189      * after a call to {@link #stopAppSwitches()}.
1190      */
1191     long mAppSwitchesAllowedTime;
1192 
1193     /**
1194      * This is set to true after the first switch after mAppSwitchesAllowedTime
1195      * is set; any switches after that will clear the time.
1196      */
1197     boolean mDidAppSwitch;
1198 
1199     /**
1200      * Last time (in realtime) at which we checked for power usage.
1201      */
1202     long mLastPowerCheckRealtime;
1203 
1204     /**
1205      * Last time (in uptime) at which we checked for power usage.
1206      */
1207     long mLastPowerCheckUptime;
1208 
1209     /**
1210      * Set while we are wanting to sleep, to prevent any
1211      * activities from being started/resumed.
1212      */
1213     private boolean mSleeping = false;
1214 
1215     /**
1216      * The process state used for processes that are running the top activities.
1217      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1218      */
1219     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1220 
1221     /**
1222      * Set while we are running a voice interaction.  This overrides
1223      * sleeping while it is active.
1224      */
1225     private IVoiceInteractionSession mRunningVoice;
1226 
1227     /**
1228      * For some direct access we need to power manager.
1229      */
1230     PowerManagerInternal mLocalPowerManager;
1231 
1232     /**
1233      * We want to hold a wake lock while running a voice interaction session, since
1234      * this may happen with the screen off and we need to keep the CPU running to
1235      * be able to continue to interact with the user.
1236      */
1237     PowerManager.WakeLock mVoiceWakeLock;
1238 
1239     /**
1240      * State of external calls telling us if the device is awake or asleep.
1241      */
1242     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1243 
1244     /**
1245      * A list of tokens that cause the top activity to be put to sleep.
1246      * They are used by components that may hide and block interaction with underlying
1247      * activities.
1248      */
1249     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1250 
1251     static final int LOCK_SCREEN_HIDDEN = 0;
1252     static final int LOCK_SCREEN_LEAVING = 1;
1253     static final int LOCK_SCREEN_SHOWN = 2;
1254     /**
1255      * State of external call telling us if the lock screen is shown.
1256      */
1257     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1258 
1259     /**
1260      * Set if we are shutting down the system, similar to sleeping.
1261      */
1262     boolean mShuttingDown = false;
1263 
1264     /**
1265      * Current sequence id for oom_adj computation traversal.
1266      */
1267     int mAdjSeq = 0;
1268 
1269     /**
1270      * Current sequence id for process LRU updating.
1271      */
1272     int mLruSeq = 0;
1273 
1274     /**
1275      * Keep track of the non-cached/empty process we last found, to help
1276      * determine how to distribute cached/empty processes next time.
1277      */
1278     int mNumNonCachedProcs = 0;
1279 
1280     /**
1281      * Keep track of the number of cached hidden procs, to balance oom adj
1282      * distribution between those and empty procs.
1283      */
1284     int mNumCachedHiddenProcs = 0;
1285 
1286     /**
1287      * Keep track of the number of service processes we last found, to
1288      * determine on the next iteration which should be B services.
1289      */
1290     int mNumServiceProcs = 0;
1291     int mNewNumAServiceProcs = 0;
1292     int mNewNumServiceProcs = 0;
1293 
1294     /**
1295      * Allow the current computed overall memory level of the system to go down?
1296      * This is set to false when we are killing processes for reasons other than
1297      * memory management, so that the now smaller process list will not be taken as
1298      * an indication that memory is tighter.
1299      */
1300     boolean mAllowLowerMemLevel = false;
1301 
1302     /**
1303      * The last computed memory level, for holding when we are in a state that
1304      * processes are going away for other reasons.
1305      */
1306     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1307 
1308     /**
1309      * The last total number of process we have, to determine if changes actually look
1310      * like a shrinking number of process due to lower RAM.
1311      */
1312     int mLastNumProcesses;
1313 
1314     /**
1315      * The uptime of the last time we performed idle maintenance.
1316      */
1317     long mLastIdleTime = SystemClock.uptimeMillis();
1318 
1319     /**
1320      * Total time spent with RAM that has been added in the past since the last idle time.
1321      */
1322     long mLowRamTimeSinceLastIdle = 0;
1323 
1324     /**
1325      * If RAM is currently low, when that horrible situation started.
1326      */
1327     long mLowRamStartTime = 0;
1328 
1329     /**
1330      * For reporting to battery stats the current top application.
1331      */
1332     private String mCurResumedPackage = null;
1333     private int mCurResumedUid = -1;
1334 
1335     /**
1336      * For reporting to battery stats the apps currently running foreground
1337      * service.  The ProcessMap is package/uid tuples; each of these contain
1338      * an array of the currently foreground processes.
1339      */
1340     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1341             = new ProcessMap<ArrayList<ProcessRecord>>();
1342 
1343     /**
1344      * This is set if we had to do a delayed dexopt of an app before launching
1345      * it, to increase the ANR timeouts in that case.
1346      */
1347     boolean mDidDexOpt;
1348 
1349     /**
1350      * Set if the systemServer made a call to enterSafeMode.
1351      */
1352     boolean mSafeMode;
1353 
1354     /**
1355      * If true, we are running under a test environment so will sample PSS from processes
1356      * much more rapidly to try to collect better data when the tests are rapidly
1357      * running through apps.
1358      */
1359     boolean mTestPssMode = false;
1360 
1361     String mDebugApp = null;
1362     boolean mWaitForDebugger = false;
1363     boolean mDebugTransient = false;
1364     String mOrigDebugApp = null;
1365     boolean mOrigWaitForDebugger = false;
1366     boolean mAlwaysFinishActivities = false;
1367     boolean mLenientBackgroundCheck = false;
1368     boolean mForceResizableActivities;
1369     boolean mSupportsMultiWindow;
1370     boolean mSupportsFreeformWindowManagement;
1371     boolean mSupportsPictureInPicture;
1372     boolean mSupportsLeanbackOnly;
1373     Rect mDefaultPinnedStackBounds;
1374     IActivityController mController = null;
1375     boolean mControllerIsAMonkey = false;
1376     String mProfileApp = null;
1377     ProcessRecord mProfileProc = null;
1378     String mProfileFile;
1379     ParcelFileDescriptor mProfileFd;
1380     int mSamplingInterval = 0;
1381     boolean mAutoStopProfiler = false;
1382     int mProfileType = 0;
1383     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1384     String mMemWatchDumpProcName;
1385     String mMemWatchDumpFile;
1386     int mMemWatchDumpPid;
1387     int mMemWatchDumpUid;
1388     String mTrackAllocationApp = null;
1389     String mNativeDebuggingApp = null;
1390 
1391     final long[] mTmpLong = new long[2];
1392 
1393     static final class ProcessChangeItem {
1394         static final int CHANGE_ACTIVITIES = 1<<0;
1395         static final int CHANGE_PROCESS_STATE = 1<<1;
1396         int changes;
1397         int uid;
1398         int pid;
1399         int processState;
1400         boolean foregroundActivities;
1401     }
1402 
1403     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1404     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1405 
1406     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1407     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1408 
1409     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1410     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1411 
1412     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1413     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1414 
1415     /**
1416      * Runtime CPU use collection thread.  This object's lock is used to
1417      * perform synchronization with the thread (notifying it to run).
1418      */
1419     final Thread mProcessCpuThread;
1420 
1421     /**
1422      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1423      * Must acquire this object's lock when accessing it.
1424      * NOTE: this lock will be held while doing long operations (trawling
1425      * through all processes in /proc), so it should never be acquired by
1426      * any critical paths such as when holding the main activity manager lock.
1427      */
1428     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1429             MONITOR_THREAD_CPU_USAGE);
1430     final AtomicLong mLastCpuTime = new AtomicLong(0);
1431     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1432 
1433     long mLastWriteTime = 0;
1434 
1435     /**
1436      * Used to retain an update lock when the foreground activity is in
1437      * immersive mode.
1438      */
1439     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1440 
1441     /**
1442      * Set to true after the system has finished booting.
1443      */
1444     boolean mBooted = false;
1445 
1446     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1447     int mProcessLimitOverride = -1;
1448 
1449     WindowManagerService mWindowManager;
1450     final ActivityThread mSystemThread;
1451 
1452     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1453         final ProcessRecord mApp;
1454         final int mPid;
1455         final IApplicationThread mAppThread;
1456 
AppDeathRecipient(ProcessRecord app, int pid, IApplicationThread thread)1457         AppDeathRecipient(ProcessRecord app, int pid,
1458                 IApplicationThread thread) {
1459             if (DEBUG_ALL) Slog.v(
1460                 TAG, "New death recipient " + this
1461                 + " for thread " + thread.asBinder());
1462             mApp = app;
1463             mPid = pid;
1464             mAppThread = thread;
1465         }
1466 
1467         @Override
binderDied()1468         public void binderDied() {
1469             if (DEBUG_ALL) Slog.v(
1470                 TAG, "Death received in " + this
1471                 + " for thread " + mAppThread.asBinder());
1472             synchronized(ActivityManagerService.this) {
1473                 appDiedLocked(mApp, mPid, mAppThread, true);
1474             }
1475         }
1476     }
1477 
1478     static final int SHOW_ERROR_UI_MSG = 1;
1479     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1480     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1481     static final int UPDATE_CONFIGURATION_MSG = 4;
1482     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1483     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1484     static final int SERVICE_TIMEOUT_MSG = 12;
1485     static final int UPDATE_TIME_ZONE = 13;
1486     static final int SHOW_UID_ERROR_UI_MSG = 14;
1487     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1488     static final int PROC_START_TIMEOUT_MSG = 20;
1489     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1490     static final int KILL_APPLICATION_MSG = 22;
1491     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1492     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1493     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1494     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1495     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1496     static final int CLEAR_DNS_CACHE_MSG = 28;
1497     static final int UPDATE_HTTP_PROXY_MSG = 29;
1498     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1499     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1500     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1501     static final int REPORT_MEM_USAGE_MSG = 33;
1502     static final int REPORT_USER_SWITCH_MSG = 34;
1503     static final int CONTINUE_USER_SWITCH_MSG = 35;
1504     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1505     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1506     static final int PERSIST_URI_GRANTS_MSG = 38;
1507     static final int REQUEST_ALL_PSS_MSG = 39;
1508     static final int START_PROFILES_MSG = 40;
1509     static final int UPDATE_TIME = 41;
1510     static final int SYSTEM_USER_START_MSG = 42;
1511     static final int SYSTEM_USER_CURRENT_MSG = 43;
1512     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1513     static final int FINISH_BOOTING_MSG = 45;
1514     static final int START_USER_SWITCH_UI_MSG = 46;
1515     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1516     static final int DISMISS_DIALOG_UI_MSG = 48;
1517     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1518     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1519     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1520     static final int DELETE_DUMPHEAP_MSG = 52;
1521     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1522     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1523     static final int REPORT_TIME_TRACKER_MSG = 55;
1524     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1525     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1526     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1527     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1528     static final int IDLE_UIDS_MSG = 60;
1529     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1530     static final int LOG_STACK_STATE = 62;
1531     static final int VR_MODE_CHANGE_MSG = 63;
1532     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1533     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1534     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1535     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1536     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1537     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1538     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1539 
1540     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1541     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1542     static final int FIRST_COMPAT_MODE_MSG = 300;
1543     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1544 
1545     static ServiceThread sKillThread = null;
1546     static KillHandler sKillHandler = null;
1547 
1548     CompatModeDialog mCompatModeDialog;
1549     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1550     long mLastMemUsageReportTime = 0;
1551 
1552     /**
1553      * Flag whether the current user is a "monkey", i.e. whether
1554      * the UI is driven by a UI automation tool.
1555      */
1556     private boolean mUserIsMonkey;
1557 
1558     /** Flag whether the device has a Recents UI */
1559     boolean mHasRecents;
1560 
1561     /** The dimensions of the thumbnails in the Recents UI. */
1562     int mThumbnailWidth;
1563     int mThumbnailHeight;
1564     float mFullscreenThumbnailScale;
1565 
1566     final ServiceThread mHandlerThread;
1567     final MainHandler mHandler;
1568     final UiHandler mUiHandler;
1569 
1570     PackageManagerInternal mPackageManagerInt;
1571 
1572     // VoiceInteraction session ID that changes for each new request except when
1573     // being called for multiwindow assist in a single session.
1574     private int mViSessionId = 1000;
1575 
1576     final class KillHandler extends Handler {
1577         static final int KILL_PROCESS_GROUP_MSG = 4000;
1578 
KillHandler(Looper looper)1579         public KillHandler(Looper looper) {
1580             super(looper, null, true);
1581         }
1582 
1583         @Override
handleMessage(Message msg)1584         public void handleMessage(Message msg) {
1585             switch (msg.what) {
1586                 case KILL_PROCESS_GROUP_MSG:
1587                 {
1588                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1589                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1590                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1591                 }
1592                 break;
1593 
1594                 default:
1595                     super.handleMessage(msg);
1596             }
1597         }
1598     }
1599 
1600     final class UiHandler extends Handler {
UiHandler()1601         public UiHandler() {
1602             super(com.android.server.UiThread.get().getLooper(), null, true);
1603         }
1604 
1605         @Override
handleMessage(Message msg)1606         public void handleMessage(Message msg) {
1607             switch (msg.what) {
1608             case SHOW_ERROR_UI_MSG: {
1609                 mAppErrors.handleShowAppErrorUi(msg);
1610                 ensureBootCompleted();
1611             } break;
1612             case SHOW_NOT_RESPONDING_UI_MSG: {
1613                 mAppErrors.handleShowAnrUi(msg);
1614                 ensureBootCompleted();
1615             } break;
1616             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1617                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1618                 synchronized (ActivityManagerService.this) {
1619                     ProcessRecord proc = (ProcessRecord) data.get("app");
1620                     if (proc == null) {
1621                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1622                         break;
1623                     }
1624                     if (proc.crashDialog != null) {
1625                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1626                         return;
1627                     }
1628                     AppErrorResult res = (AppErrorResult) data.get("result");
1629                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1630                         Dialog d = new StrictModeViolationDialog(mContext,
1631                                 ActivityManagerService.this, res, proc);
1632                         d.show();
1633                         proc.crashDialog = d;
1634                     } else {
1635                         // The device is asleep, so just pretend that the user
1636                         // saw a crash dialog and hit "force quit".
1637                         res.set(0);
1638                     }
1639                 }
1640                 ensureBootCompleted();
1641             } break;
1642             case SHOW_FACTORY_ERROR_UI_MSG: {
1643                 Dialog d = new FactoryErrorDialog(
1644                     mContext, msg.getData().getCharSequence("msg"));
1645                 d.show();
1646                 ensureBootCompleted();
1647             } break;
1648             case WAIT_FOR_DEBUGGER_UI_MSG: {
1649                 synchronized (ActivityManagerService.this) {
1650                     ProcessRecord app = (ProcessRecord)msg.obj;
1651                     if (msg.arg1 != 0) {
1652                         if (!app.waitedForDebugger) {
1653                             Dialog d = new AppWaitingForDebuggerDialog(
1654                                     ActivityManagerService.this,
1655                                     mContext, app);
1656                             app.waitDialog = d;
1657                             app.waitedForDebugger = true;
1658                             d.show();
1659                         }
1660                     } else {
1661                         if (app.waitDialog != null) {
1662                             app.waitDialog.dismiss();
1663                             app.waitDialog = null;
1664                         }
1665                     }
1666                 }
1667             } break;
1668             case SHOW_UID_ERROR_UI_MSG: {
1669                 if (mShowDialogs) {
1670                     AlertDialog d = new BaseErrorDialog(mContext);
1671                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1672                     d.setCancelable(false);
1673                     d.setTitle(mContext.getText(R.string.android_system_label));
1674                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1675                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1676                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1677                     d.show();
1678                 }
1679             } break;
1680             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1681                 if (mShowDialogs) {
1682                     AlertDialog d = new BaseErrorDialog(mContext);
1683                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1684                     d.setCancelable(false);
1685                     d.setTitle(mContext.getText(R.string.android_system_label));
1686                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1687                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1688                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1689                     d.show();
1690                 }
1691             } break;
1692             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1693                 synchronized (ActivityManagerService.this) {
1694                     ActivityRecord ar = (ActivityRecord) msg.obj;
1695                     if (mCompatModeDialog != null) {
1696                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1697                                 ar.info.applicationInfo.packageName)) {
1698                             return;
1699                         }
1700                         mCompatModeDialog.dismiss();
1701                         mCompatModeDialog = null;
1702                     }
1703                     if (ar != null && false) {
1704                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1705                                 ar.packageName)) {
1706                             int mode = mCompatModePackages.computeCompatModeLocked(
1707                                     ar.info.applicationInfo);
1708                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1709                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1710                                 mCompatModeDialog = new CompatModeDialog(
1711                                         ActivityManagerService.this, mContext,
1712                                         ar.info.applicationInfo);
1713                                 mCompatModeDialog.show();
1714                             }
1715                         }
1716                     }
1717                 }
1718                 break;
1719             }
1720             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1721                 synchronized (ActivityManagerService.this) {
1722                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1723                     if (mUnsupportedDisplaySizeDialog != null) {
1724                         mUnsupportedDisplaySizeDialog.dismiss();
1725                         mUnsupportedDisplaySizeDialog = null;
1726                     }
1727                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1728                             ar.packageName)) {
1729                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1730                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1731                         mUnsupportedDisplaySizeDialog.show();
1732                     }
1733                 }
1734                 break;
1735             }
1736             case START_USER_SWITCH_UI_MSG: {
1737                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1738                 break;
1739             }
1740             case DISMISS_DIALOG_UI_MSG: {
1741                 final Dialog d = (Dialog) msg.obj;
1742                 d.dismiss();
1743                 break;
1744             }
1745             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1746                 dispatchProcessesChanged();
1747                 break;
1748             }
1749             case DISPATCH_PROCESS_DIED_UI_MSG: {
1750                 final int pid = msg.arg1;
1751                 final int uid = msg.arg2;
1752                 dispatchProcessDied(pid, uid);
1753                 break;
1754             }
1755             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1756                 dispatchUidsChanged();
1757             } break;
1758             }
1759         }
1760     }
1761 
1762     final class MainHandler extends Handler {
MainHandler(Looper looper)1763         public MainHandler(Looper looper) {
1764             super(looper, null, true);
1765         }
1766 
1767         @Override
handleMessage(Message msg)1768         public void handleMessage(Message msg) {
1769             switch (msg.what) {
1770             case UPDATE_CONFIGURATION_MSG: {
1771                 final ContentResolver resolver = mContext.getContentResolver();
1772                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1773                         msg.arg1);
1774             } break;
1775             case GC_BACKGROUND_PROCESSES_MSG: {
1776                 synchronized (ActivityManagerService.this) {
1777                     performAppGcsIfAppropriateLocked();
1778                 }
1779             } break;
1780             case SERVICE_TIMEOUT_MSG: {
1781                 if (mDidDexOpt) {
1782                     mDidDexOpt = false;
1783                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1784                     nmsg.obj = msg.obj;
1785                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1786                     return;
1787                 }
1788                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1789             } break;
1790             case UPDATE_TIME_ZONE: {
1791                 synchronized (ActivityManagerService.this) {
1792                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1793                         ProcessRecord r = mLruProcesses.get(i);
1794                         if (r.thread != null) {
1795                             try {
1796                                 r.thread.updateTimeZone();
1797                             } catch (RemoteException ex) {
1798                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1799                             }
1800                         }
1801                     }
1802                 }
1803             } break;
1804             case CLEAR_DNS_CACHE_MSG: {
1805                 synchronized (ActivityManagerService.this) {
1806                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1807                         ProcessRecord r = mLruProcesses.get(i);
1808                         if (r.thread != null) {
1809                             try {
1810                                 r.thread.clearDnsCache();
1811                             } catch (RemoteException ex) {
1812                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1813                             }
1814                         }
1815                     }
1816                 }
1817             } break;
1818             case UPDATE_HTTP_PROXY_MSG: {
1819                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1820                 String host = "";
1821                 String port = "";
1822                 String exclList = "";
1823                 Uri pacFileUrl = Uri.EMPTY;
1824                 if (proxy != null) {
1825                     host = proxy.getHost();
1826                     port = Integer.toString(proxy.getPort());
1827                     exclList = proxy.getExclusionListAsString();
1828                     pacFileUrl = proxy.getPacFileUrl();
1829                 }
1830                 synchronized (ActivityManagerService.this) {
1831                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1832                         ProcessRecord r = mLruProcesses.get(i);
1833                         if (r.thread != null) {
1834                             try {
1835                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1836                             } catch (RemoteException ex) {
1837                                 Slog.w(TAG, "Failed to update http proxy for: " +
1838                                         r.info.processName);
1839                             }
1840                         }
1841                     }
1842                 }
1843             } break;
1844             case PROC_START_TIMEOUT_MSG: {
1845                 if (mDidDexOpt) {
1846                     mDidDexOpt = false;
1847                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1848                     nmsg.obj = msg.obj;
1849                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1850                     return;
1851                 }
1852                 ProcessRecord app = (ProcessRecord)msg.obj;
1853                 synchronized (ActivityManagerService.this) {
1854                     processStartTimedOutLocked(app);
1855                 }
1856             } break;
1857             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1858                 ProcessRecord app = (ProcessRecord)msg.obj;
1859                 synchronized (ActivityManagerService.this) {
1860                     processContentProviderPublishTimedOutLocked(app);
1861                 }
1862             } break;
1863             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1864                 synchronized (ActivityManagerService.this) {
1865                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1866                 }
1867             } break;
1868             case KILL_APPLICATION_MSG: {
1869                 synchronized (ActivityManagerService.this) {
1870                     final int appId = msg.arg1;
1871                     final int userId = msg.arg2;
1872                     Bundle bundle = (Bundle)msg.obj;
1873                     String pkg = bundle.getString("pkg");
1874                     String reason = bundle.getString("reason");
1875                     forceStopPackageLocked(pkg, appId, false, false, true, false,
1876                             false, userId, reason);
1877                 }
1878             } break;
1879             case FINALIZE_PENDING_INTENT_MSG: {
1880                 ((PendingIntentRecord)msg.obj).completeFinalize();
1881             } break;
1882             case POST_HEAVY_NOTIFICATION_MSG: {
1883                 INotificationManager inm = NotificationManager.getService();
1884                 if (inm == null) {
1885                     return;
1886                 }
1887 
1888                 ActivityRecord root = (ActivityRecord)msg.obj;
1889                 ProcessRecord process = root.app;
1890                 if (process == null) {
1891                     return;
1892                 }
1893 
1894                 try {
1895                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1896                     String text = mContext.getString(R.string.heavy_weight_notification,
1897                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1898                     Notification notification = new Notification.Builder(context)
1899                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1900                             .setWhen(0)
1901                             .setOngoing(true)
1902                             .setTicker(text)
1903                             .setColor(mContext.getColor(
1904                                     com.android.internal.R.color.system_notification_accent_color))
1905                             .setContentTitle(text)
1906                             .setContentText(
1907                                     mContext.getText(R.string.heavy_weight_notification_detail))
1908                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1909                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1910                                     new UserHandle(root.userId)))
1911                             .build();
1912                     try {
1913                         int[] outId = new int[1];
1914                         inm.enqueueNotificationWithTag("android", "android", null,
1915                                 R.string.heavy_weight_notification,
1916                                 notification, outId, root.userId);
1917                     } catch (RuntimeException e) {
1918                         Slog.w(ActivityManagerService.TAG,
1919                                 "Error showing notification for heavy-weight app", e);
1920                     } catch (RemoteException e) {
1921                     }
1922                 } catch (NameNotFoundException e) {
1923                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1924                 }
1925             } break;
1926             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1927                 INotificationManager inm = NotificationManager.getService();
1928                 if (inm == null) {
1929                     return;
1930                 }
1931                 try {
1932                     inm.cancelNotificationWithTag("android", null,
1933                             R.string.heavy_weight_notification,  msg.arg1);
1934                 } catch (RuntimeException e) {
1935                     Slog.w(ActivityManagerService.TAG,
1936                             "Error canceling notification for service", e);
1937                 } catch (RemoteException e) {
1938                 }
1939             } break;
1940             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1941                 synchronized (ActivityManagerService.this) {
1942                     checkExcessivePowerUsageLocked(true);
1943                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1944                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1945                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1946                 }
1947             } break;
1948             case REPORT_MEM_USAGE_MSG: {
1949                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1950                 Thread thread = new Thread() {
1951                     @Override public void run() {
1952                         reportMemUsage(memInfos);
1953                     }
1954                 };
1955                 thread.start();
1956                 break;
1957             }
1958             case REPORT_USER_SWITCH_MSG: {
1959                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1960                 break;
1961             }
1962             case CONTINUE_USER_SWITCH_MSG: {
1963                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1964                 break;
1965             }
1966             case USER_SWITCH_TIMEOUT_MSG: {
1967                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1968                 break;
1969             }
1970             case IMMERSIVE_MODE_LOCK_MSG: {
1971                 final boolean nextState = (msg.arg1 != 0);
1972                 if (mUpdateLock.isHeld() != nextState) {
1973                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1974                             "Applying new update lock state '" + nextState
1975                             + "' for " + (ActivityRecord)msg.obj);
1976                     if (nextState) {
1977                         mUpdateLock.acquire();
1978                     } else {
1979                         mUpdateLock.release();
1980                     }
1981                 }
1982                 break;
1983             }
1984             case PERSIST_URI_GRANTS_MSG: {
1985                 writeGrantedUriPermissions();
1986                 break;
1987             }
1988             case REQUEST_ALL_PSS_MSG: {
1989                 synchronized (ActivityManagerService.this) {
1990                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1991                 }
1992                 break;
1993             }
1994             case START_PROFILES_MSG: {
1995                 synchronized (ActivityManagerService.this) {
1996                     mUserController.startProfilesLocked();
1997                 }
1998                 break;
1999             }
2000             case UPDATE_TIME: {
2001                 synchronized (ActivityManagerService.this) {
2002                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2003                         ProcessRecord r = mLruProcesses.get(i);
2004                         if (r.thread != null) {
2005                             try {
2006                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2007                             } catch (RemoteException ex) {
2008                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2009                             }
2010                         }
2011                     }
2012                 }
2013                 break;
2014             }
2015             case SYSTEM_USER_START_MSG: {
2016                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2017                         Integer.toString(msg.arg1), msg.arg1);
2018                 mSystemServiceManager.startUser(msg.arg1);
2019                 break;
2020             }
2021             case SYSTEM_USER_UNLOCK_MSG: {
2022                 final int userId = msg.arg1;
2023                 mSystemServiceManager.unlockUser(userId);
2024                 synchronized (ActivityManagerService.this) {
2025                     mRecentTasks.loadUserRecentsLocked(userId);
2026                 }
2027                 if (userId == UserHandle.USER_SYSTEM) {
2028                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2029                 }
2030                 installEncryptionUnawareProviders(userId);
2031                 mUserController.finishUserUnlocked((UserState) msg.obj);
2032                 break;
2033             }
2034             case SYSTEM_USER_CURRENT_MSG: {
2035                 mBatteryStatsService.noteEvent(
2036                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2037                         Integer.toString(msg.arg2), msg.arg2);
2038                 mBatteryStatsService.noteEvent(
2039                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2040                         Integer.toString(msg.arg1), msg.arg1);
2041                 mSystemServiceManager.switchUser(msg.arg1);
2042                 break;
2043             }
2044             case ENTER_ANIMATION_COMPLETE_MSG: {
2045                 synchronized (ActivityManagerService.this) {
2046                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2047                     if (r != null && r.app != null && r.app.thread != null) {
2048                         try {
2049                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2050                         } catch (RemoteException e) {
2051                         }
2052                     }
2053                 }
2054                 break;
2055             }
2056             case FINISH_BOOTING_MSG: {
2057                 if (msg.arg1 != 0) {
2058                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2059                     finishBooting();
2060                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2061                 }
2062                 if (msg.arg2 != 0) {
2063                     enableScreenAfterBoot();
2064                 }
2065                 break;
2066             }
2067             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2068                 try {
2069                     Locale l = (Locale) msg.obj;
2070                     IBinder service = ServiceManager.getService("mount");
2071                     IMountService mountService = IMountService.Stub.asInterface(service);
2072                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2073                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2074                 } catch (RemoteException e) {
2075                     Log.e(TAG, "Error storing locale for decryption UI", e);
2076                 }
2077                 break;
2078             }
2079             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2080                 synchronized (ActivityManagerService.this) {
2081                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2082                         try {
2083                             // Make a one-way callback to the listener
2084                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2085                         } catch (RemoteException e){
2086                             // Handled by the RemoteCallbackList
2087                         }
2088                     }
2089                     mTaskStackListeners.finishBroadcast();
2090                 }
2091                 break;
2092             }
2093             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2094                 synchronized (ActivityManagerService.this) {
2095                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2096                         try {
2097                             // Make a one-way callback to the listener
2098                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2099                         } catch (RemoteException e){
2100                             // Handled by the RemoteCallbackList
2101                         }
2102                     }
2103                     mTaskStackListeners.finishBroadcast();
2104                 }
2105                 break;
2106             }
2107             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2108                 synchronized (ActivityManagerService.this) {
2109                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2110                         try {
2111                             // Make a one-way callback to the listener
2112                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2113                         } catch (RemoteException e){
2114                             // Handled by the RemoteCallbackList
2115                         }
2116                     }
2117                     mTaskStackListeners.finishBroadcast();
2118                 }
2119                 break;
2120             }
2121             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2122                 synchronized (ActivityManagerService.this) {
2123                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2124                         try {
2125                             // Make a one-way callback to the listener
2126                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2127                         } catch (RemoteException e){
2128                             // Handled by the RemoteCallbackList
2129                         }
2130                     }
2131                     mTaskStackListeners.finishBroadcast();
2132                 }
2133                 break;
2134             }
2135             case NOTIFY_FORCED_RESIZABLE_MSG: {
2136                 synchronized (ActivityManagerService.this) {
2137                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2138                         try {
2139                             // Make a one-way callback to the listener
2140                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2141                                     (String) msg.obj, msg.arg1);
2142                         } catch (RemoteException e){
2143                             // Handled by the RemoteCallbackList
2144                         }
2145                     }
2146                     mTaskStackListeners.finishBroadcast();
2147                 }
2148                 break;
2149             }
2150                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2151                     synchronized (ActivityManagerService.this) {
2152                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2153                             try {
2154                                 // Make a one-way callback to the listener
2155                                 mTaskStackListeners.getBroadcastItem(i)
2156                                         .onActivityDismissingDockedStack();
2157                             } catch (RemoteException e){
2158                                 // Handled by the RemoteCallbackList
2159                             }
2160                         }
2161                         mTaskStackListeners.finishBroadcast();
2162                     }
2163                     break;
2164                 }
2165             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2166                 final int uid = msg.arg1;
2167                 final byte[] firstPacket = (byte[]) msg.obj;
2168 
2169                 synchronized (mPidsSelfLocked) {
2170                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2171                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2172                         if (p.uid == uid) {
2173                             try {
2174                                 p.thread.notifyCleartextNetwork(firstPacket);
2175                             } catch (RemoteException ignored) {
2176                             }
2177                         }
2178                     }
2179                 }
2180                 break;
2181             }
2182             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2183                 final String procName;
2184                 final int uid;
2185                 final long memLimit;
2186                 final String reportPackage;
2187                 synchronized (ActivityManagerService.this) {
2188                     procName = mMemWatchDumpProcName;
2189                     uid = mMemWatchDumpUid;
2190                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2191                     if (val == null) {
2192                         val = mMemWatchProcesses.get(procName, 0);
2193                     }
2194                     if (val != null) {
2195                         memLimit = val.first;
2196                         reportPackage = val.second;
2197                     } else {
2198                         memLimit = 0;
2199                         reportPackage = null;
2200                     }
2201                 }
2202                 if (procName == null) {
2203                     return;
2204                 }
2205 
2206                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2207                         "Showing dump heap notification from " + procName + "/" + uid);
2208 
2209                 INotificationManager inm = NotificationManager.getService();
2210                 if (inm == null) {
2211                     return;
2212                 }
2213 
2214                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2215 
2216 
2217                 Intent deleteIntent = new Intent();
2218                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2219                 Intent intent = new Intent();
2220                 intent.setClassName("android", DumpHeapActivity.class.getName());
2221                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2222                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2223                 if (reportPackage != null) {
2224                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2225                 }
2226                 int userId = UserHandle.getUserId(uid);
2227                 Notification notification = new Notification.Builder(mContext)
2228                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2229                         .setWhen(0)
2230                         .setOngoing(true)
2231                         .setAutoCancel(true)
2232                         .setTicker(text)
2233                         .setColor(mContext.getColor(
2234                                 com.android.internal.R.color.system_notification_accent_color))
2235                         .setContentTitle(text)
2236                         .setContentText(
2237                                 mContext.getText(R.string.dump_heap_notification_detail))
2238                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2239                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2240                                 new UserHandle(userId)))
2241                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2242                                 deleteIntent, 0, UserHandle.SYSTEM))
2243                         .build();
2244 
2245                 try {
2246                     int[] outId = new int[1];
2247                     inm.enqueueNotificationWithTag("android", "android", null,
2248                             R.string.dump_heap_notification,
2249                             notification, outId, userId);
2250                 } catch (RuntimeException e) {
2251                     Slog.w(ActivityManagerService.TAG,
2252                             "Error showing notification for dump heap", e);
2253                 } catch (RemoteException e) {
2254                 }
2255             } break;
2256             case DELETE_DUMPHEAP_MSG: {
2257                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2258                         DumpHeapActivity.JAVA_URI,
2259                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2260                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2261                         UserHandle.myUserId());
2262                 synchronized (ActivityManagerService.this) {
2263                     mMemWatchDumpFile = null;
2264                     mMemWatchDumpProcName = null;
2265                     mMemWatchDumpPid = -1;
2266                     mMemWatchDumpUid = -1;
2267                 }
2268             } break;
2269             case FOREGROUND_PROFILE_CHANGED_MSG: {
2270                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2271             } break;
2272             case REPORT_TIME_TRACKER_MSG: {
2273                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2274                 tracker.deliverResult(mContext);
2275             } break;
2276             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2277                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2278             } break;
2279             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2280                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2281                 try {
2282                     connection.shutdown();
2283                 } catch (RemoteException e) {
2284                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2285                 }
2286                 // Only a UiAutomation can set this flag and now that
2287                 // it is finished we make sure it is reset to its default.
2288                 mUserIsMonkey = false;
2289             } break;
2290             case APP_BOOST_DEACTIVATE_MSG: {
2291                 synchronized(ActivityManagerService.this) {
2292                     if (mIsBoosted) {
2293                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2294                             nativeMigrateFromBoost();
2295                             mIsBoosted = false;
2296                             mBoostStartTime = 0;
2297                         } else {
2298                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2299                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2300                         }
2301                     }
2302                 }
2303             } break;
2304             case IDLE_UIDS_MSG: {
2305                 idleUids();
2306             } break;
2307             case LOG_STACK_STATE: {
2308                 synchronized (ActivityManagerService.this) {
2309                     mStackSupervisor.logStackState();
2310                 }
2311             } break;
2312             case VR_MODE_CHANGE_MSG: {
2313                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2314                 final ActivityRecord r = (ActivityRecord) msg.obj;
2315                 boolean vrMode;
2316                 ComponentName requestedPackage;
2317                 ComponentName callingPackage;
2318                 int userId;
2319                 synchronized (ActivityManagerService.this) {
2320                     vrMode = r.requestedVrComponent != null;
2321                     requestedPackage = r.requestedVrComponent;
2322                     userId = r.userId;
2323                     callingPackage = r.info.getComponentName();
2324                     if (mInVrMode != vrMode) {
2325                         mInVrMode = vrMode;
2326                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2327                         if (r.app != null) {
2328                             ProcessRecord proc = r.app;
2329                             if (proc.vrThreadTid > 0) {
2330                                 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2331                                     try {
2332                                         if (mInVrMode == true) {
2333                                             Process.setThreadScheduler(proc.vrThreadTid,
2334                                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2335                                         } else {
2336                                             Process.setThreadScheduler(proc.vrThreadTid,
2337                                                 Process.SCHED_OTHER, 0);
2338                                         }
2339                                     } catch (IllegalArgumentException e) {
2340                                         Slog.w(TAG, "Failed to set scheduling policy, thread does"
2341                                                 + " not exist:\n" + e);
2342                                     }
2343                                 }
2344                             }
2345                         }
2346                     }
2347                 }
2348                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2349             } break;
2350             case VR_MODE_APPLY_IF_NEEDED_MSG: {
2351                 final ActivityRecord r = (ActivityRecord) msg.obj;
2352                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2353                 if (needsVrMode) {
2354                     applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2355                             r.info.getComponentName(), false);
2356                 }
2357             } break;
2358             }
2359         }
2360     };
2361 
2362     static final int COLLECT_PSS_BG_MSG = 1;
2363 
2364     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2365         @Override
2366         public void handleMessage(Message msg) {
2367             switch (msg.what) {
2368             case COLLECT_PSS_BG_MSG: {
2369                 long start = SystemClock.uptimeMillis();
2370                 MemInfoReader memInfo = null;
2371                 synchronized (ActivityManagerService.this) {
2372                     if (mFullPssPending) {
2373                         mFullPssPending = false;
2374                         memInfo = new MemInfoReader();
2375                     }
2376                 }
2377                 if (memInfo != null) {
2378                     updateCpuStatsNow();
2379                     long nativeTotalPss = 0;
2380                     synchronized (mProcessCpuTracker) {
2381                         final int N = mProcessCpuTracker.countStats();
2382                         for (int j=0; j<N; j++) {
2383                             ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(j);
2384                             if (st.vsize <= 0 || st.uid >= Process.FIRST_APPLICATION_UID) {
2385                                 // This is definitely an application process; skip it.
2386                                 continue;
2387                             }
2388                             synchronized (mPidsSelfLocked) {
2389                                 if (mPidsSelfLocked.indexOfKey(st.pid) >= 0) {
2390                                     // This is one of our own processes; skip it.
2391                                     continue;
2392                                 }
2393                             }
2394                             nativeTotalPss += Debug.getPss(st.pid, null, null);
2395                         }
2396                     }
2397                     memInfo.readMemInfo();
2398                     synchronized (ActivityManagerService.this) {
2399                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2400                                 + (SystemClock.uptimeMillis()-start) + "ms");
2401                         final long cachedKb = memInfo.getCachedSizeKb();
2402                         final long freeKb = memInfo.getFreeSizeKb();
2403                         final long zramKb = memInfo.getZramTotalSizeKb();
2404                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2405                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2406                                 kernelKb*1024, nativeTotalPss*1024);
2407                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2408                                 nativeTotalPss);
2409                     }
2410                 }
2411 
2412                 int num = 0;
2413                 long[] tmp = new long[2];
2414                 do {
2415                     ProcessRecord proc;
2416                     int procState;
2417                     int pid;
2418                     long lastPssTime;
2419                     synchronized (ActivityManagerService.this) {
2420                         if (mPendingPssProcesses.size() <= 0) {
2421                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2422                                     "Collected PSS of " + num + " processes in "
2423                                     + (SystemClock.uptimeMillis() - start) + "ms");
2424                             mPendingPssProcesses.clear();
2425                             return;
2426                         }
2427                         proc = mPendingPssProcesses.remove(0);
2428                         procState = proc.pssProcState;
2429                         lastPssTime = proc.lastPssTime;
2430                         if (proc.thread != null && procState == proc.setProcState
2431                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2432                                         < SystemClock.uptimeMillis()) {
2433                             pid = proc.pid;
2434                         } else {
2435                             proc = null;
2436                             pid = 0;
2437                         }
2438                     }
2439                     if (proc != null) {
2440                         long pss = Debug.getPss(pid, tmp, null);
2441                         synchronized (ActivityManagerService.this) {
2442                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2443                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2444                                 num++;
2445                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2446                                         SystemClock.uptimeMillis());
2447                             }
2448                         }
2449                     }
2450                 } while (true);
2451             }
2452             }
2453         }
2454     };
2455 
setSystemProcess()2456     public void setSystemProcess() {
2457         try {
2458             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2459             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2460             ServiceManager.addService("meminfo", new MemBinder(this));
2461             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2462             ServiceManager.addService("dbinfo", new DbBinder(this));
2463             if (MONITOR_CPU_USAGE) {
2464                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2465             }
2466             ServiceManager.addService("permission", new PermissionController(this));
2467             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2468 
2469             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2470                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2471             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2472 
2473             synchronized (this) {
2474                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2475                 app.persistent = true;
2476                 app.pid = MY_PID;
2477                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2478                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2479                 synchronized (mPidsSelfLocked) {
2480                     mPidsSelfLocked.put(app.pid, app);
2481                 }
2482                 updateLruProcessLocked(app, false, null);
2483                 updateOomAdjLocked();
2484             }
2485         } catch (PackageManager.NameNotFoundException e) {
2486             throw new RuntimeException(
2487                     "Unable to find android system package", e);
2488         }
2489     }
2490 
setWindowManager(WindowManagerService wm)2491     public void setWindowManager(WindowManagerService wm) {
2492         mWindowManager = wm;
2493         mStackSupervisor.setWindowManager(wm);
2494         mActivityStarter.setWindowManager(wm);
2495     }
2496 
setUsageStatsManager(UsageStatsManagerInternal usageStatsManager)2497     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2498         mUsageStatsService = usageStatsManager;
2499     }
2500 
startObservingNativeCrashes()2501     public void startObservingNativeCrashes() {
2502         final NativeCrashListener ncl = new NativeCrashListener(this);
2503         ncl.start();
2504     }
2505 
getAppOpsService()2506     public IAppOpsService getAppOpsService() {
2507         return mAppOpsService;
2508     }
2509 
2510     static class MemBinder extends Binder {
2511         ActivityManagerService mActivityManagerService;
MemBinder(ActivityManagerService activityManagerService)2512         MemBinder(ActivityManagerService activityManagerService) {
2513             mActivityManagerService = activityManagerService;
2514         }
2515 
2516         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)2517         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2518             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2519                     != PackageManager.PERMISSION_GRANTED) {
2520                 pw.println("Permission Denial: can't dump meminfo from from pid="
2521                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2522                         + " without permission " + android.Manifest.permission.DUMP);
2523                 return;
2524             }
2525 
2526             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2527         }
2528     }
2529 
2530     static class GraphicsBinder extends Binder {
2531         ActivityManagerService mActivityManagerService;
GraphicsBinder(ActivityManagerService activityManagerService)2532         GraphicsBinder(ActivityManagerService activityManagerService) {
2533             mActivityManagerService = activityManagerService;
2534         }
2535 
2536         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)2537         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2538             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2539                     != PackageManager.PERMISSION_GRANTED) {
2540                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2541                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2542                         + " without permission " + android.Manifest.permission.DUMP);
2543                 return;
2544             }
2545 
2546             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2547         }
2548     }
2549 
2550     static class DbBinder extends Binder {
2551         ActivityManagerService mActivityManagerService;
DbBinder(ActivityManagerService activityManagerService)2552         DbBinder(ActivityManagerService activityManagerService) {
2553             mActivityManagerService = activityManagerService;
2554         }
2555 
2556         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)2557         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2558             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2559                     != PackageManager.PERMISSION_GRANTED) {
2560                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2561                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2562                         + " without permission " + android.Manifest.permission.DUMP);
2563                 return;
2564             }
2565 
2566             mActivityManagerService.dumpDbInfo(fd, pw, args);
2567         }
2568     }
2569 
2570     static class CpuBinder extends Binder {
2571         ActivityManagerService mActivityManagerService;
CpuBinder(ActivityManagerService activityManagerService)2572         CpuBinder(ActivityManagerService activityManagerService) {
2573             mActivityManagerService = activityManagerService;
2574         }
2575 
2576         @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)2577         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2578             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2579                     != PackageManager.PERMISSION_GRANTED) {
2580                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2581                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2582                         + " without permission " + android.Manifest.permission.DUMP);
2583                 return;
2584             }
2585 
2586             synchronized (mActivityManagerService.mProcessCpuTracker) {
2587                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2588                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2589                         SystemClock.uptimeMillis()));
2590             }
2591         }
2592     }
2593 
2594     public static final class Lifecycle extends SystemService {
2595         private final ActivityManagerService mService;
2596 
Lifecycle(Context context)2597         public Lifecycle(Context context) {
2598             super(context);
2599             mService = new ActivityManagerService(context);
2600         }
2601 
2602         @Override
onStart()2603         public void onStart() {
2604             mService.start();
2605         }
2606 
getService()2607         public ActivityManagerService getService() {
2608             return mService;
2609         }
2610     }
2611 
2612     // Note: This method is invoked on the main thread but may need to attach various
2613     // handlers to other threads.  So take care to be explicit about the looper.
ActivityManagerService(Context systemContext)2614     public ActivityManagerService(Context systemContext) {
2615         mContext = systemContext;
2616         mFactoryTest = FactoryTest.getMode();
2617         mSystemThread = ActivityThread.currentActivityThread();
2618 
2619         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2620 
2621         mHandlerThread = new ServiceThread(TAG,
2622                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2623         mHandlerThread.start();
2624         mHandler = new MainHandler(mHandlerThread.getLooper());
2625         mUiHandler = new UiHandler();
2626 
2627         /* static; one-time init here */
2628         if (sKillHandler == null) {
2629             sKillThread = new ServiceThread(TAG + ":kill",
2630                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2631             sKillThread.start();
2632             sKillHandler = new KillHandler(sKillThread.getLooper());
2633         }
2634 
2635         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2636                 "foreground", BROADCAST_FG_TIMEOUT, false);
2637         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2638                 "background", BROADCAST_BG_TIMEOUT, true);
2639         mBroadcastQueues[0] = mFgBroadcastQueue;
2640         mBroadcastQueues[1] = mBgBroadcastQueue;
2641 
2642         mServices = new ActiveServices(this);
2643         mProviderMap = new ProviderMap(this);
2644         mAppErrors = new AppErrors(mContext, this);
2645 
2646         // TODO: Move creation of battery stats service outside of activity manager service.
2647         File dataDir = Environment.getDataDirectory();
2648         File systemDir = new File(dataDir, "system");
2649         systemDir.mkdirs();
2650         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2651         mBatteryStatsService.getActiveStatistics().readLocked();
2652         mBatteryStatsService.scheduleWriteToDisk();
2653         mOnBattery = DEBUG_POWER ? true
2654                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2655         mBatteryStatsService.getActiveStatistics().setCallback(this);
2656 
2657         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2658 
2659         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2660         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2661                 new IAppOpsCallback.Stub() {
2662                     @Override public void opChanged(int op, int uid, String packageName) {
2663                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2664                             if (mAppOpsService.checkOperation(op, uid, packageName)
2665                                     != AppOpsManager.MODE_ALLOWED) {
2666                                 runInBackgroundDisabled(uid);
2667                             }
2668                         }
2669                     }
2670                 });
2671 
2672         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2673 
2674         mUserController = new UserController(this);
2675 
2676         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2677             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2678 
2679         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2680             mUseFifoUiScheduling = true;
2681         }
2682 
2683         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2684 
2685         mConfiguration.setToDefaults();
2686         mConfiguration.setLocales(LocaleList.getDefault());
2687 
2688         mConfigurationSeq = mConfiguration.seq = 1;
2689         mProcessCpuTracker.init();
2690 
2691         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2692         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2693         mStackSupervisor = new ActivityStackSupervisor(this);
2694         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2695         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2696 
2697         mProcessCpuThread = new Thread("CpuTracker") {
2698             @Override
2699             public void run() {
2700                 while (true) {
2701                     try {
2702                         try {
2703                             synchronized(this) {
2704                                 final long now = SystemClock.uptimeMillis();
2705                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2706                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2707                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2708                                 //        + ", write delay=" + nextWriteDelay);
2709                                 if (nextWriteDelay < nextCpuDelay) {
2710                                     nextCpuDelay = nextWriteDelay;
2711                                 }
2712                                 if (nextCpuDelay > 0) {
2713                                     mProcessCpuMutexFree.set(true);
2714                                     this.wait(nextCpuDelay);
2715                                 }
2716                             }
2717                         } catch (InterruptedException e) {
2718                         }
2719                         updateCpuStatsNow();
2720                     } catch (Exception e) {
2721                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2722                     }
2723                 }
2724             }
2725         };
2726 
2727         Watchdog.getInstance().addMonitor(this);
2728         Watchdog.getInstance().addThread(mHandler);
2729     }
2730 
setSystemServiceManager(SystemServiceManager mgr)2731     public void setSystemServiceManager(SystemServiceManager mgr) {
2732         mSystemServiceManager = mgr;
2733     }
2734 
setInstaller(Installer installer)2735     public void setInstaller(Installer installer) {
2736         mInstaller = installer;
2737     }
2738 
start()2739     private void start() {
2740         Process.removeAllProcessGroups();
2741         mProcessCpuThread.start();
2742 
2743         mBatteryStatsService.publish(mContext);
2744         mAppOpsService.publish(mContext);
2745         Slog.d("AppOps", "AppOpsService published");
2746         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2747     }
2748 
onUserStoppedLocked(int userId)2749     void onUserStoppedLocked(int userId) {
2750         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2751     }
2752 
initPowerManagement()2753     public void initPowerManagement() {
2754         mStackSupervisor.initPowerManagement();
2755         mBatteryStatsService.initPowerManagement();
2756         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2757         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2758         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2759         mVoiceWakeLock.setReferenceCounted(false);
2760     }
2761 
2762     @Override
onTransact(int code, Parcel data, Parcel reply, int flags)2763     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2764             throws RemoteException {
2765         if (code == SYSPROPS_TRANSACTION) {
2766             // We need to tell all apps about the system property change.
2767             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2768             synchronized(this) {
2769                 final int NP = mProcessNames.getMap().size();
2770                 for (int ip=0; ip<NP; ip++) {
2771                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2772                     final int NA = apps.size();
2773                     for (int ia=0; ia<NA; ia++) {
2774                         ProcessRecord app = apps.valueAt(ia);
2775                         if (app.thread != null) {
2776                             procs.add(app.thread.asBinder());
2777                         }
2778                     }
2779                 }
2780             }
2781 
2782             int N = procs.size();
2783             for (int i=0; i<N; i++) {
2784                 Parcel data2 = Parcel.obtain();
2785                 try {
2786                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2787                 } catch (RemoteException e) {
2788                 }
2789                 data2.recycle();
2790             }
2791         }
2792         try {
2793             return super.onTransact(code, data, reply, flags);
2794         } catch (RuntimeException e) {
2795             // The activity manager only throws security exceptions, so let's
2796             // log all others.
2797             if (!(e instanceof SecurityException)) {
2798                 Slog.wtf(TAG, "Activity Manager Crash", e);
2799             }
2800             throw e;
2801         }
2802     }
2803 
updateCpuStats()2804     void updateCpuStats() {
2805         final long now = SystemClock.uptimeMillis();
2806         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2807             return;
2808         }
2809         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2810             synchronized (mProcessCpuThread) {
2811                 mProcessCpuThread.notify();
2812             }
2813         }
2814     }
2815 
updateCpuStatsNow()2816     void updateCpuStatsNow() {
2817         synchronized (mProcessCpuTracker) {
2818             mProcessCpuMutexFree.set(false);
2819             final long now = SystemClock.uptimeMillis();
2820             boolean haveNewCpuStats = false;
2821 
2822             if (MONITOR_CPU_USAGE &&
2823                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2824                 mLastCpuTime.set(now);
2825                 mProcessCpuTracker.update();
2826                 if (mProcessCpuTracker.hasGoodLastStats()) {
2827                     haveNewCpuStats = true;
2828                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2829                     //Slog.i(TAG, "Total CPU usage: "
2830                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2831 
2832                     // Slog the cpu usage if the property is set.
2833                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2834                         int user = mProcessCpuTracker.getLastUserTime();
2835                         int system = mProcessCpuTracker.getLastSystemTime();
2836                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2837                         int irq = mProcessCpuTracker.getLastIrqTime();
2838                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2839                         int idle = mProcessCpuTracker.getLastIdleTime();
2840 
2841                         int total = user + system + iowait + irq + softIrq + idle;
2842                         if (total == 0) total = 1;
2843 
2844                         EventLog.writeEvent(EventLogTags.CPU,
2845                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2846                                 (user * 100) / total,
2847                                 (system * 100) / total,
2848                                 (iowait * 100) / total,
2849                                 (irq * 100) / total,
2850                                 (softIrq * 100) / total);
2851                     }
2852                 }
2853             }
2854 
2855             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2856             synchronized(bstats) {
2857                 synchronized(mPidsSelfLocked) {
2858                     if (haveNewCpuStats) {
2859                         if (bstats.startAddingCpuLocked()) {
2860                             int totalUTime = 0;
2861                             int totalSTime = 0;
2862                             final int N = mProcessCpuTracker.countStats();
2863                             for (int i=0; i<N; i++) {
2864                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2865                                 if (!st.working) {
2866                                     continue;
2867                                 }
2868                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2869                                 totalUTime += st.rel_utime;
2870                                 totalSTime += st.rel_stime;
2871                                 if (pr != null) {
2872                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2873                                     if (ps == null || !ps.isActive()) {
2874                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2875                                                 pr.info.uid, pr.processName);
2876                                     }
2877                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2878                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2879                                 } else {
2880                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2881                                     if (ps == null || !ps.isActive()) {
2882                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2883                                                 bstats.mapUid(st.uid), st.name);
2884                                     }
2885                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2886                                 }
2887                             }
2888                             final int userTime = mProcessCpuTracker.getLastUserTime();
2889                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2890                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2891                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2892                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2893                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2894                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2895                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2896                         }
2897                     }
2898                 }
2899 
2900                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2901                     mLastWriteTime = now;
2902                     mBatteryStatsService.scheduleWriteToDisk();
2903                 }
2904             }
2905         }
2906     }
2907 
2908     @Override
batteryNeedsCpuUpdate()2909     public void batteryNeedsCpuUpdate() {
2910         updateCpuStatsNow();
2911     }
2912 
2913     @Override
batteryPowerChanged(boolean onBattery)2914     public void batteryPowerChanged(boolean onBattery) {
2915         // When plugging in, update the CPU stats first before changing
2916         // the plug state.
2917         updateCpuStatsNow();
2918         synchronized (this) {
2919             synchronized(mPidsSelfLocked) {
2920                 mOnBattery = DEBUG_POWER ? true : onBattery;
2921             }
2922         }
2923     }
2924 
2925     @Override
batterySendBroadcast(Intent intent)2926     public void batterySendBroadcast(Intent intent) {
2927         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2928                 AppOpsManager.OP_NONE, null, false, false,
2929                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2930     }
2931 
2932     /**
2933      * Initialize the application bind args. These are passed to each
2934      * process when the bindApplication() IPC is sent to the process. They're
2935      * lazily setup to make sure the services are running when they're asked for.
2936      */
getCommonServicesLocked(boolean isolated)2937     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2938         if (mAppBindArgs == null) {
2939             mAppBindArgs = new HashMap<>();
2940 
2941             // Isolated processes won't get this optimization, so that we don't
2942             // violate the rules about which services they have access to.
2943             if (!isolated) {
2944                 // Setup the application init args
2945                 mAppBindArgs.put("package", ServiceManager.getService("package"));
2946                 mAppBindArgs.put("window", ServiceManager.getService("window"));
2947                 mAppBindArgs.put(Context.ALARM_SERVICE,
2948                         ServiceManager.getService(Context.ALARM_SERVICE));
2949             }
2950         }
2951         return mAppBindArgs;
2952     }
2953 
setFocusedActivityLocked(ActivityRecord r, String reason)2954     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2955         if (r == null || mFocusedActivity == r) {
2956             return false;
2957         }
2958 
2959         if (!r.isFocusable()) {
2960             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2961             return false;
2962         }
2963 
2964         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2965 
2966         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2967         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2968                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2969         mDoingSetFocusedActivity = true;
2970 
2971         final ActivityRecord last = mFocusedActivity;
2972         mFocusedActivity = r;
2973         if (r.task.isApplicationTask()) {
2974             if (mCurAppTimeTracker != r.appTimeTracker) {
2975                 // We are switching app tracking.  Complete the current one.
2976                 if (mCurAppTimeTracker != null) {
2977                     mCurAppTimeTracker.stop();
2978                     mHandler.obtainMessage(
2979                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2980                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2981                     mCurAppTimeTracker = null;
2982                 }
2983                 if (r.appTimeTracker != null) {
2984                     mCurAppTimeTracker = r.appTimeTracker;
2985                     startTimeTrackingFocusedActivityLocked();
2986                 }
2987             } else {
2988                 startTimeTrackingFocusedActivityLocked();
2989             }
2990         } else {
2991             r.appTimeTracker = null;
2992         }
2993         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
2994         // TODO: Probably not, because we don't want to resume voice on switching
2995         // back to this activity
2996         if (r.task.voiceInteractor != null) {
2997             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
2998         } else {
2999             finishRunningVoiceLocked();
3000             IVoiceInteractionSession session;
3001             if (last != null && ((session = last.task.voiceSession) != null
3002                     || (session = last.voiceSession) != null)) {
3003                 // We had been in a voice interaction session, but now focused has
3004                 // move to something different.  Just finish the session, we can't
3005                 // return to it and retain the proper state and synchronization with
3006                 // the voice interaction service.
3007                 finishVoiceTask(session);
3008             }
3009         }
3010         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3011             mWindowManager.setFocusedApp(r.appToken, true);
3012         }
3013         applyUpdateLockStateLocked(r);
3014         applyUpdateVrModeLocked(r);
3015         if (mFocusedActivity.userId != mLastFocusedUserId) {
3016             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3017             mHandler.obtainMessage(
3018                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3019             mLastFocusedUserId = mFocusedActivity.userId;
3020         }
3021 
3022         // Log a warning if the focused app is changed during the process. This could
3023         // indicate a problem of the focus setting logic!
3024         if (mFocusedActivity != r) Slog.w(TAG,
3025                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3026         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3027 
3028         EventLogTags.writeAmFocusedActivity(
3029                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3030                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3031                 reason);
3032         return true;
3033     }
3034 
resetFocusedActivityIfNeededLocked(ActivityRecord goingAway)3035     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3036         if (mFocusedActivity != goingAway) {
3037             return;
3038         }
3039 
3040         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3041         if (focusedStack != null) {
3042             final ActivityRecord top = focusedStack.topActivity();
3043             if (top != null && top.userId != mLastFocusedUserId) {
3044                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3045                 mHandler.sendMessage(
3046                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3047                 mLastFocusedUserId = top.userId;
3048             }
3049         }
3050 
3051         // Try to move focus to another activity if possible.
3052         if (setFocusedActivityLocked(
3053                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3054             return;
3055         }
3056 
3057         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3058                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3059         mFocusedActivity = null;
3060         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3061     }
3062 
3063     @Override
setFocusedStack(int stackId)3064     public void setFocusedStack(int stackId) {
3065         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3066         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3067         final long callingId = Binder.clearCallingIdentity();
3068         try {
3069             synchronized (this) {
3070                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3071                 if (stack == null) {
3072                     return;
3073                 }
3074                 final ActivityRecord r = stack.topRunningActivityLocked();
3075                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3076                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3077                 }
3078             }
3079         } finally {
3080             Binder.restoreCallingIdentity(callingId);
3081         }
3082     }
3083 
3084     @Override
setFocusedTask(int taskId)3085     public void setFocusedTask(int taskId) {
3086         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3087         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3088         final long callingId = Binder.clearCallingIdentity();
3089         try {
3090             synchronized (this) {
3091                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3092                 if (task == null) {
3093                     return;
3094                 }
3095                 if (mUserController.shouldConfirmCredentials(task.userId)) {
3096                     mActivityStarter.showConfirmDeviceCredential(task.userId);
3097                     if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3098                         mStackSupervisor.moveTaskToStackLocked(task.taskId,
3099                                 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3100                                 "setFocusedTask", ANIMATE);
3101                     }
3102                     return;
3103                 }
3104                 final ActivityRecord r = task.topRunningActivityLocked();
3105                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3106                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3107                 }
3108             }
3109         } finally {
3110             Binder.restoreCallingIdentity(callingId);
3111         }
3112     }
3113 
3114     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3115     @Override
registerTaskStackListener(ITaskStackListener listener)3116     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3117         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3118         synchronized (this) {
3119             if (listener != null) {
3120                 mTaskStackListeners.register(listener);
3121             }
3122         }
3123     }
3124 
3125     @Override
notifyActivityDrawn(IBinder token)3126     public void notifyActivityDrawn(IBinder token) {
3127         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3128         synchronized (this) {
3129             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3130             if (r != null) {
3131                 r.task.stack.notifyActivityDrawnLocked(r);
3132             }
3133         }
3134     }
3135 
applyUpdateLockStateLocked(ActivityRecord r)3136     final void applyUpdateLockStateLocked(ActivityRecord r) {
3137         // Modifications to the UpdateLock state are done on our handler, outside
3138         // the activity manager's locks.  The new state is determined based on the
3139         // state *now* of the relevant activity record.  The object is passed to
3140         // the handler solely for logging detail, not to be consulted/modified.
3141         final boolean nextState = r != null && r.immersive;
3142         mHandler.sendMessage(
3143                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3144     }
3145 
applyUpdateVrModeLocked(ActivityRecord r)3146     final void applyUpdateVrModeLocked(ActivityRecord r) {
3147         mHandler.sendMessage(
3148                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3149     }
3150 
applyVrModeIfNeededLocked(ActivityRecord r, boolean enable)3151     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3152         mHandler.sendMessage(
3153                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3154     }
3155 
applyVrMode(boolean enabled, ComponentName packageName, int userId, ComponentName callingPackage, boolean immediate)3156     private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3157             ComponentName callingPackage, boolean immediate) {
3158         VrManagerInternal vrService =
3159                 LocalServices.getService(VrManagerInternal.class);
3160         if (immediate) {
3161             vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3162         } else {
3163             vrService.setVrMode(enabled, packageName, userId, callingPackage);
3164         }
3165     }
3166 
showAskCompatModeDialogLocked(ActivityRecord r)3167     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3168         Message msg = Message.obtain();
3169         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3170         msg.obj = r.task.askedCompatMode ? null : r;
3171         mUiHandler.sendMessage(msg);
3172     }
3173 
showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r)3174     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3175         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3176                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3177             final Message msg = Message.obtain();
3178             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3179             msg.obj = r;
3180             mUiHandler.sendMessage(msg);
3181         }
3182     }
3183 
updateLruProcessInternalLocked(ProcessRecord app, long now, int index, String what, Object obj, ProcessRecord srcApp)3184     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3185             String what, Object obj, ProcessRecord srcApp) {
3186         app.lastActivityTime = now;
3187 
3188         if (app.activities.size() > 0) {
3189             // Don't want to touch dependent processes that are hosting activities.
3190             return index;
3191         }
3192 
3193         int lrui = mLruProcesses.lastIndexOf(app);
3194         if (lrui < 0) {
3195             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3196                     + what + " " + obj + " from " + srcApp);
3197             return index;
3198         }
3199 
3200         if (lrui >= index) {
3201             // Don't want to cause this to move dependent processes *back* in the
3202             // list as if they were less frequently used.
3203             return index;
3204         }
3205 
3206         if (lrui >= mLruProcessActivityStart) {
3207             // Don't want to touch dependent processes that are hosting activities.
3208             return index;
3209         }
3210 
3211         mLruProcesses.remove(lrui);
3212         if (index > 0) {
3213             index--;
3214         }
3215         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3216                 + " in LRU list: " + app);
3217         mLruProcesses.add(index, app);
3218         return index;
3219     }
3220 
killProcessGroup(int uid, int pid)3221     static void killProcessGroup(int uid, int pid) {
3222         if (sKillHandler != null) {
3223             sKillHandler.sendMessage(
3224                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3225         } else {
3226             Slog.w(TAG, "Asked to kill process group before system bringup!");
3227             Process.killProcessGroup(uid, pid);
3228         }
3229     }
3230 
removeLruProcessLocked(ProcessRecord app)3231     final void removeLruProcessLocked(ProcessRecord app) {
3232         int lrui = mLruProcesses.lastIndexOf(app);
3233         if (lrui >= 0) {
3234             if (!app.killed) {
3235                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3236                 Process.killProcessQuiet(app.pid);
3237                 killProcessGroup(app.uid, app.pid);
3238             }
3239             if (lrui <= mLruProcessActivityStart) {
3240                 mLruProcessActivityStart--;
3241             }
3242             if (lrui <= mLruProcessServiceStart) {
3243                 mLruProcessServiceStart--;
3244             }
3245             mLruProcesses.remove(lrui);
3246         }
3247     }
3248 
updateLruProcessLocked(ProcessRecord app, boolean activityChange, ProcessRecord client)3249     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3250             ProcessRecord client) {
3251         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3252                 || app.treatLikeActivity;
3253         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3254         if (!activityChange && hasActivity) {
3255             // The process has activities, so we are only allowing activity-based adjustments
3256             // to move it.  It should be kept in the front of the list with other
3257             // processes that have activities, and we don't want those to change their
3258             // order except due to activity operations.
3259             return;
3260         }
3261 
3262         mLruSeq++;
3263         final long now = SystemClock.uptimeMillis();
3264         app.lastActivityTime = now;
3265 
3266         // First a quick reject: if the app is already at the position we will
3267         // put it, then there is nothing to do.
3268         if (hasActivity) {
3269             final int N = mLruProcesses.size();
3270             if (N > 0 && mLruProcesses.get(N-1) == app) {
3271                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3272                 return;
3273             }
3274         } else {
3275             if (mLruProcessServiceStart > 0
3276                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3277                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3278                 return;
3279             }
3280         }
3281 
3282         int lrui = mLruProcesses.lastIndexOf(app);
3283 
3284         if (app.persistent && lrui >= 0) {
3285             // We don't care about the position of persistent processes, as long as
3286             // they are in the list.
3287             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3288             return;
3289         }
3290 
3291         /* In progress: compute new position first, so we can avoid doing work
3292            if the process is not actually going to move.  Not yet working.
3293         int addIndex;
3294         int nextIndex;
3295         boolean inActivity = false, inService = false;
3296         if (hasActivity) {
3297             // Process has activities, put it at the very tipsy-top.
3298             addIndex = mLruProcesses.size();
3299             nextIndex = mLruProcessServiceStart;
3300             inActivity = true;
3301         } else if (hasService) {
3302             // Process has services, put it at the top of the service list.
3303             addIndex = mLruProcessActivityStart;
3304             nextIndex = mLruProcessServiceStart;
3305             inActivity = true;
3306             inService = true;
3307         } else  {
3308             // Process not otherwise of interest, it goes to the top of the non-service area.
3309             addIndex = mLruProcessServiceStart;
3310             if (client != null) {
3311                 int clientIndex = mLruProcesses.lastIndexOf(client);
3312                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3313                         + app);
3314                 if (clientIndex >= 0 && addIndex > clientIndex) {
3315                     addIndex = clientIndex;
3316                 }
3317             }
3318             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3319         }
3320 
3321         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3322                 + mLruProcessActivityStart + "): " + app);
3323         */
3324 
3325         if (lrui >= 0) {
3326             if (lrui < mLruProcessActivityStart) {
3327                 mLruProcessActivityStart--;
3328             }
3329             if (lrui < mLruProcessServiceStart) {
3330                 mLruProcessServiceStart--;
3331             }
3332             /*
3333             if (addIndex > lrui) {
3334                 addIndex--;
3335             }
3336             if (nextIndex > lrui) {
3337                 nextIndex--;
3338             }
3339             */
3340             mLruProcesses.remove(lrui);
3341         }
3342 
3343         /*
3344         mLruProcesses.add(addIndex, app);
3345         if (inActivity) {
3346             mLruProcessActivityStart++;
3347         }
3348         if (inService) {
3349             mLruProcessActivityStart++;
3350         }
3351         */
3352 
3353         int nextIndex;
3354         if (hasActivity) {
3355             final int N = mLruProcesses.size();
3356             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3357                 // Process doesn't have activities, but has clients with
3358                 // activities...  move it up, but one below the top (the top
3359                 // should always have a real activity).
3360                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3361                         "Adding to second-top of LRU activity list: " + app);
3362                 mLruProcesses.add(N - 1, app);
3363                 // To keep it from spamming the LRU list (by making a bunch of clients),
3364                 // we will push down any other entries owned by the app.
3365                 final int uid = app.info.uid;
3366                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3367                     ProcessRecord subProc = mLruProcesses.get(i);
3368                     if (subProc.info.uid == uid) {
3369                         // We want to push this one down the list.  If the process after
3370                         // it is for the same uid, however, don't do so, because we don't
3371                         // want them internally to be re-ordered.
3372                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3373                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3374                                     "Pushing uid " + uid + " swapping at " + i + ": "
3375                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3376                             ProcessRecord tmp = mLruProcesses.get(i);
3377                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3378                             mLruProcesses.set(i - 1, tmp);
3379                             i--;
3380                         }
3381                     } else {
3382                         // A gap, we can stop here.
3383                         break;
3384                     }
3385                 }
3386             } else {
3387                 // Process has activities, put it at the very tipsy-top.
3388                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3389                 mLruProcesses.add(app);
3390             }
3391             nextIndex = mLruProcessServiceStart;
3392         } else if (hasService) {
3393             // Process has services, put it at the top of the service list.
3394             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3395             mLruProcesses.add(mLruProcessActivityStart, app);
3396             nextIndex = mLruProcessServiceStart;
3397             mLruProcessActivityStart++;
3398         } else  {
3399             // Process not otherwise of interest, it goes to the top of the non-service area.
3400             int index = mLruProcessServiceStart;
3401             if (client != null) {
3402                 // If there is a client, don't allow the process to be moved up higher
3403                 // in the list than that client.
3404                 int clientIndex = mLruProcesses.lastIndexOf(client);
3405                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3406                         + " when updating " + app);
3407                 if (clientIndex <= lrui) {
3408                     // Don't allow the client index restriction to push it down farther in the
3409                     // list than it already is.
3410                     clientIndex = lrui;
3411                 }
3412                 if (clientIndex >= 0 && index > clientIndex) {
3413                     index = clientIndex;
3414                 }
3415             }
3416             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3417             mLruProcesses.add(index, app);
3418             nextIndex = index-1;
3419             mLruProcessActivityStart++;
3420             mLruProcessServiceStart++;
3421         }
3422 
3423         // If the app is currently using a content provider or service,
3424         // bump those processes as well.
3425         for (int j=app.connections.size()-1; j>=0; j--) {
3426             ConnectionRecord cr = app.connections.valueAt(j);
3427             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3428                     && cr.binding.service.app != null
3429                     && cr.binding.service.app.lruSeq != mLruSeq
3430                     && !cr.binding.service.app.persistent) {
3431                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3432                         "service connection", cr, app);
3433             }
3434         }
3435         for (int j=app.conProviders.size()-1; j>=0; j--) {
3436             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3437             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3438                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3439                         "provider reference", cpr, app);
3440             }
3441         }
3442     }
3443 
getProcessRecordLocked(String processName, int uid, boolean keepIfLarge)3444     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3445         if (uid == Process.SYSTEM_UID) {
3446             // The system gets to run in any process.  If there are multiple
3447             // processes with the same uid, just pick the first (this
3448             // should never happen).
3449             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3450             if (procs == null) return null;
3451             final int procCount = procs.size();
3452             for (int i = 0; i < procCount; i++) {
3453                 final int procUid = procs.keyAt(i);
3454                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3455                     // Don't use an app process or different user process for system component.
3456                     continue;
3457                 }
3458                 return procs.valueAt(i);
3459             }
3460         }
3461         ProcessRecord proc = mProcessNames.get(processName, uid);
3462         if (false && proc != null && !keepIfLarge
3463                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3464                 && proc.lastCachedPss >= 4000) {
3465             // Turn this condition on to cause killing to happen regularly, for testing.
3466             if (proc.baseProcessTracker != null) {
3467                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3468             }
3469             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3470         } else if (proc != null && !keepIfLarge
3471                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3472                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3473             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3474             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3475                 if (proc.baseProcessTracker != null) {
3476                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3477                 }
3478                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3479             }
3480         }
3481         return proc;
3482     }
3483 
notifyPackageUse(String packageName, int reason)3484     void notifyPackageUse(String packageName, int reason) {
3485         IPackageManager pm = AppGlobals.getPackageManager();
3486         try {
3487             pm.notifyPackageUse(packageName, reason);
3488         } catch (RemoteException e) {
3489         }
3490     }
3491 
isNextTransitionForward()3492     boolean isNextTransitionForward() {
3493         int transit = mWindowManager.getPendingAppTransition();
3494         return transit == TRANSIT_ACTIVITY_OPEN
3495                 || transit == TRANSIT_TASK_OPEN
3496                 || transit == TRANSIT_TASK_TO_FRONT;
3497     }
3498 
startIsolatedProcess(String entryPoint, String[] entryPointArgs, String processName, String abiOverride, int uid, Runnable crashHandler)3499     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3500             String processName, String abiOverride, int uid, Runnable crashHandler) {
3501         synchronized(this) {
3502             ApplicationInfo info = new ApplicationInfo();
3503             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3504             // For isolated processes, the former contains the parent's uid and the latter the
3505             // actual uid of the isolated process.
3506             // In the special case introduced by this method (which is, starting an isolated
3507             // process directly from the SystemServer without an actual parent app process) the
3508             // closest thing to a parent's uid is SYSTEM_UID.
3509             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3510             // the |isolated| logic in the ProcessRecord constructor.
3511             info.uid = Process.SYSTEM_UID;
3512             info.processName = processName;
3513             info.className = entryPoint;
3514             info.packageName = "android";
3515             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3516                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3517                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3518                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3519                     crashHandler);
3520             return proc != null ? proc.pid : 0;
3521         }
3522     }
3523 
startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, boolean keepIfLarge)3524     final ProcessRecord startProcessLocked(String processName,
3525             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3526             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3527             boolean isolated, boolean keepIfLarge) {
3528         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3529                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3530                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3531                 null /* crashHandler */);
3532     }
3533 
startProcessLocked(String processName, ApplicationInfo info, boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName, boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge, String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler)3534     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3535             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3536             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3537             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3538         long startTime = SystemClock.elapsedRealtime();
3539         ProcessRecord app;
3540         if (!isolated) {
3541             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3542             checkTime(startTime, "startProcess: after getProcessRecord");
3543 
3544             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3545                 // If we are in the background, then check to see if this process
3546                 // is bad.  If so, we will just silently fail.
3547                 if (mAppErrors.isBadProcessLocked(info)) {
3548                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3549                             + "/" + info.processName);
3550                     return null;
3551                 }
3552             } else {
3553                 // When the user is explicitly starting a process, then clear its
3554                 // crash count so that we won't make it bad until they see at
3555                 // least one crash dialog again, and make the process good again
3556                 // if it had been bad.
3557                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3558                         + "/" + info.processName);
3559                 mAppErrors.resetProcessCrashTimeLocked(info);
3560                 if (mAppErrors.isBadProcessLocked(info)) {
3561                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3562                             UserHandle.getUserId(info.uid), info.uid,
3563                             info.processName);
3564                     mAppErrors.clearBadProcessLocked(info);
3565                     if (app != null) {
3566                         app.bad = false;
3567                     }
3568                 }
3569             }
3570         } else {
3571             // If this is an isolated process, it can't re-use an existing process.
3572             app = null;
3573         }
3574 
3575         // app launch boost for big.little configurations
3576         // use cpusets to migrate freshly launched tasks to big cores
3577         nativeMigrateToBoost();
3578         mIsBoosted = true;
3579         mBoostStartTime = SystemClock.uptimeMillis();
3580         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3581         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3582 
3583         // We don't have to do anything more if:
3584         // (1) There is an existing application record; and
3585         // (2) The caller doesn't think it is dead, OR there is no thread
3586         //     object attached to it so we know it couldn't have crashed; and
3587         // (3) There is a pid assigned to it, so it is either starting or
3588         //     already running.
3589         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3590                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3591                 + " thread=" + (app != null ? app.thread : null)
3592                 + " pid=" + (app != null ? app.pid : -1));
3593         if (app != null && app.pid > 0) {
3594             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3595                 // We already have the app running, or are waiting for it to
3596                 // come up (we have a pid but not yet its thread), so keep it.
3597                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3598                 // If this is a new package in the process, add the package to the list
3599                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3600                 checkTime(startTime, "startProcess: done, added package to proc");
3601                 return app;
3602             }
3603 
3604             // An application record is attached to a previous process,
3605             // clean it up now.
3606             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3607             checkTime(startTime, "startProcess: bad proc running, killing");
3608             killProcessGroup(app.uid, app.pid);
3609             handleAppDiedLocked(app, true, true);
3610             checkTime(startTime, "startProcess: done killing old proc");
3611         }
3612 
3613         String hostingNameStr = hostingName != null
3614                 ? hostingName.flattenToShortString() : null;
3615 
3616         if (app == null) {
3617             checkTime(startTime, "startProcess: creating new process record");
3618             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3619             if (app == null) {
3620                 Slog.w(TAG, "Failed making new process record for "
3621                         + processName + "/" + info.uid + " isolated=" + isolated);
3622                 return null;
3623             }
3624             app.crashHandler = crashHandler;
3625             checkTime(startTime, "startProcess: done creating new process record");
3626         } else {
3627             // If this is a new package in the process, add the package to the list
3628             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3629             checkTime(startTime, "startProcess: added package to existing proc");
3630         }
3631 
3632         // If the system is not ready yet, then hold off on starting this
3633         // process until it is.
3634         if (!mProcessesReady
3635                 && !isAllowedWhileBooting(info)
3636                 && !allowWhileBooting) {
3637             if (!mProcessesOnHold.contains(app)) {
3638                 mProcessesOnHold.add(app);
3639             }
3640             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3641                     "System not ready, putting on hold: " + app);
3642             checkTime(startTime, "startProcess: returning with proc on hold");
3643             return app;
3644         }
3645 
3646         checkTime(startTime, "startProcess: stepping in to startProcess");
3647         startProcessLocked(
3648                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3649         checkTime(startTime, "startProcess: done starting proc!");
3650         return (app.pid != 0) ? app : null;
3651     }
3652 
isAllowedWhileBooting(ApplicationInfo ai)3653     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3654         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3655     }
3656 
startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr)3657     private final void startProcessLocked(ProcessRecord app,
3658             String hostingType, String hostingNameStr) {
3659         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3660                 null /* entryPoint */, null /* entryPointArgs */);
3661     }
3662 
startProcessLocked(ProcessRecord app, String hostingType, String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs)3663     private final void startProcessLocked(ProcessRecord app, String hostingType,
3664             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3665         long startTime = SystemClock.elapsedRealtime();
3666         if (app.pid > 0 && app.pid != MY_PID) {
3667             checkTime(startTime, "startProcess: removing from pids map");
3668             synchronized (mPidsSelfLocked) {
3669                 mPidsSelfLocked.remove(app.pid);
3670                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3671             }
3672             checkTime(startTime, "startProcess: done removing from pids map");
3673             app.setPid(0);
3674         }
3675 
3676         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3677                 "startProcessLocked removing on hold: " + app);
3678         mProcessesOnHold.remove(app);
3679 
3680         checkTime(startTime, "startProcess: starting to update cpu stats");
3681         updateCpuStats();
3682         checkTime(startTime, "startProcess: done updating cpu stats");
3683 
3684         try {
3685             try {
3686                 final int userId = UserHandle.getUserId(app.uid);
3687                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3688             } catch (RemoteException e) {
3689                 throw e.rethrowAsRuntimeException();
3690             }
3691 
3692             int uid = app.uid;
3693             int[] gids = null;
3694             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3695             if (!app.isolated) {
3696                 int[] permGids = null;
3697                 try {
3698                     checkTime(startTime, "startProcess: getting gids from package manager");
3699                     final IPackageManager pm = AppGlobals.getPackageManager();
3700                     permGids = pm.getPackageGids(app.info.packageName,
3701                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3702                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3703                             MountServiceInternal.class);
3704                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3705                             app.info.packageName);
3706                 } catch (RemoteException e) {
3707                     throw e.rethrowAsRuntimeException();
3708                 }
3709 
3710                 /*
3711                  * Add shared application and profile GIDs so applications can share some
3712                  * resources like shared libraries and access user-wide resources
3713                  */
3714                 if (ArrayUtils.isEmpty(permGids)) {
3715                     gids = new int[2];
3716                 } else {
3717                     gids = new int[permGids.length + 2];
3718                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3719                 }
3720                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3721                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3722             }
3723             checkTime(startTime, "startProcess: building args");
3724             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3725                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3726                         && mTopComponent != null
3727                         && app.processName.equals(mTopComponent.getPackageName())) {
3728                     uid = 0;
3729                 }
3730                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3731                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3732                     uid = 0;
3733                 }
3734             }
3735             int debugFlags = 0;
3736             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3737                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3738                 // Also turn on CheckJNI for debuggable apps. It's quite
3739                 // awkward to turn on otherwise.
3740                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3741             }
3742             // Run the app in safe mode if its manifest requests so or the
3743             // system is booted in safe mode.
3744             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3745                 mSafeMode == true) {
3746                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3747             }
3748             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3749                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3750             }
3751             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3752             if ("true".equals(genDebugInfoProperty)) {
3753                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3754             }
3755             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3756                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3757             }
3758             if ("1".equals(SystemProperties.get("debug.assert"))) {
3759                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3760             }
3761             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3762                 // Enable all debug flags required by the native debugger.
3763                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3764                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3765                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3766                 mNativeDebuggingApp = null;
3767             }
3768 
3769             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3770             if (requiredAbi == null) {
3771                 requiredAbi = Build.SUPPORTED_ABIS[0];
3772             }
3773 
3774             String instructionSet = null;
3775             if (app.info.primaryCpuAbi != null) {
3776                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3777             }
3778 
3779             app.gids = gids;
3780             app.requiredAbi = requiredAbi;
3781             app.instructionSet = instructionSet;
3782 
3783             // Start the process.  It will either succeed and return a result containing
3784             // the PID of the new process, or else throw a RuntimeException.
3785             boolean isActivityProcess = (entryPoint == null);
3786             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3787             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3788                     app.processName);
3789             checkTime(startTime, "startProcess: asking zygote to start proc");
3790             Process.ProcessStartResult startResult = Process.start(entryPoint,
3791                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3792                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3793                     app.info.dataDir, entryPointArgs);
3794             checkTime(startTime, "startProcess: returned from zygote!");
3795             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3796 
3797             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3798             checkTime(startTime, "startProcess: done updating battery stats");
3799 
3800             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3801                     UserHandle.getUserId(uid), startResult.pid, uid,
3802                     app.processName, hostingType,
3803                     hostingNameStr != null ? hostingNameStr : "");
3804 
3805             try {
3806                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3807                         app.info.seinfo, app.info.sourceDir, startResult.pid);
3808             } catch (RemoteException ex) {
3809                 // Ignore
3810             }
3811 
3812             if (app.persistent) {
3813                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3814             }
3815 
3816             checkTime(startTime, "startProcess: building log message");
3817             StringBuilder buf = mStringBuilder;
3818             buf.setLength(0);
3819             buf.append("Start proc ");
3820             buf.append(startResult.pid);
3821             buf.append(':');
3822             buf.append(app.processName);
3823             buf.append('/');
3824             UserHandle.formatUid(buf, uid);
3825             if (!isActivityProcess) {
3826                 buf.append(" [");
3827                 buf.append(entryPoint);
3828                 buf.append("]");
3829             }
3830             buf.append(" for ");
3831             buf.append(hostingType);
3832             if (hostingNameStr != null) {
3833                 buf.append(" ");
3834                 buf.append(hostingNameStr);
3835             }
3836             Slog.i(TAG, buf.toString());
3837             app.setPid(startResult.pid);
3838             app.usingWrapper = startResult.usingWrapper;
3839             app.removed = false;
3840             app.killed = false;
3841             app.killedByAm = false;
3842             checkTime(startTime, "startProcess: starting to update pids map");
3843             ProcessRecord oldApp;
3844             synchronized (mPidsSelfLocked) {
3845                 oldApp = mPidsSelfLocked.get(startResult.pid);
3846             }
3847             // If there is already an app occupying that pid that hasn't been cleaned up
3848             if (oldApp != null && !app.isolated) {
3849                 // Clean up anything relating to this pid first
3850                 Slog.w(TAG, "Reusing pid " + startResult.pid
3851                         + " while app is still mapped to it");
3852                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3853                         true /*replacingPid*/);
3854             }
3855             synchronized (mPidsSelfLocked) {
3856                 this.mPidsSelfLocked.put(startResult.pid, app);
3857                 if (isActivityProcess) {
3858                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3859                     msg.obj = app;
3860                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3861                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3862                 }
3863             }
3864             checkTime(startTime, "startProcess: done updating pids map");
3865         } catch (RuntimeException e) {
3866             Slog.e(TAG, "Failure starting process " + app.processName, e);
3867 
3868             // Something went very wrong while trying to start this process; one
3869             // common case is when the package is frozen due to an active
3870             // upgrade. To recover, clean up any active bookkeeping related to
3871             // starting this process. (We already invoked this method once when
3872             // the package was initially frozen through KILL_APPLICATION_MSG, so
3873             // it doesn't hurt to use it again.)
3874             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3875                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3876         }
3877     }
3878 
updateUsageStats(ActivityRecord component, boolean resumed)3879     void updateUsageStats(ActivityRecord component, boolean resumed) {
3880         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3881                 "updateUsageStats: comp=" + component + "res=" + resumed);
3882         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3883         if (resumed) {
3884             if (mUsageStatsService != null) {
3885                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3886                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3887             }
3888             synchronized (stats) {
3889                 stats.noteActivityResumedLocked(component.app.uid);
3890             }
3891         } else {
3892             if (mUsageStatsService != null) {
3893                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3894                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3895             }
3896             synchronized (stats) {
3897                 stats.noteActivityPausedLocked(component.app.uid);
3898             }
3899         }
3900     }
3901 
getHomeIntent()3902     Intent getHomeIntent() {
3903         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3904         intent.setComponent(mTopComponent);
3905         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3906         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3907             intent.addCategory(Intent.CATEGORY_HOME);
3908         }
3909         return intent;
3910     }
3911 
startHomeActivityLocked(int userId, String reason)3912     boolean startHomeActivityLocked(int userId, String reason) {
3913         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3914                 && mTopAction == null) {
3915             // We are running in factory test mode, but unable to find
3916             // the factory test app, so just sit around displaying the
3917             // error message and don't try to start anything.
3918             return false;
3919         }
3920         Intent intent = getHomeIntent();
3921         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3922         if (aInfo != null) {
3923             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3924             // Don't do this if the home app is currently being
3925             // instrumented.
3926             aInfo = new ActivityInfo(aInfo);
3927             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3928             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3929                     aInfo.applicationInfo.uid, true);
3930             if (app == null || app.instrumentationClass == null) {
3931                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3932                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3933             }
3934         } else {
3935             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3936         }
3937 
3938         return true;
3939     }
3940 
resolveActivityInfo(Intent intent, int flags, int userId)3941     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3942         ActivityInfo ai = null;
3943         ComponentName comp = intent.getComponent();
3944         try {
3945             if (comp != null) {
3946                 // Factory test.
3947                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3948             } else {
3949                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3950                         intent,
3951                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3952                         flags, userId);
3953 
3954                 if (info != null) {
3955                     ai = info.activityInfo;
3956                 }
3957             }
3958         } catch (RemoteException e) {
3959             // ignore
3960         }
3961 
3962         return ai;
3963     }
3964 
3965     /**
3966      * Starts the "new version setup screen" if appropriate.
3967      */
startSetupActivityLocked()3968     void startSetupActivityLocked() {
3969         // Only do this once per boot.
3970         if (mCheckedForSetup) {
3971             return;
3972         }
3973 
3974         // We will show this screen if the current one is a different
3975         // version than the last one shown, and we are not running in
3976         // low-level factory test mode.
3977         final ContentResolver resolver = mContext.getContentResolver();
3978         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3979                 Settings.Global.getInt(resolver,
3980                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3981             mCheckedForSetup = true;
3982 
3983             // See if we should be showing the platform update setup UI.
3984             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
3985             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
3986                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
3987             if (!ris.isEmpty()) {
3988                 final ResolveInfo ri = ris.get(0);
3989                 String vers = ri.activityInfo.metaData != null
3990                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
3991                         : null;
3992                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
3993                     vers = ri.activityInfo.applicationInfo.metaData.getString(
3994                             Intent.METADATA_SETUP_VERSION);
3995                 }
3996                 String lastVers = Settings.Secure.getString(
3997                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
3998                 if (vers != null && !vers.equals(lastVers)) {
3999                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4000                     intent.setComponent(new ComponentName(
4001                             ri.activityInfo.packageName, ri.activityInfo.name));
4002                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4003                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4004                             null, 0, 0, 0, null, false, false, null, null, null);
4005                 }
4006             }
4007         }
4008     }
4009 
compatibilityInfoForPackageLocked(ApplicationInfo ai)4010     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4011         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4012     }
4013 
enforceNotIsolatedCaller(String caller)4014     void enforceNotIsolatedCaller(String caller) {
4015         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4016             throw new SecurityException("Isolated process not allowed to call " + caller);
4017         }
4018     }
4019 
enforceShellRestriction(String restriction, int userHandle)4020     void enforceShellRestriction(String restriction, int userHandle) {
4021         if (Binder.getCallingUid() == Process.SHELL_UID) {
4022             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4023                 throw new SecurityException("Shell does not have permission to access user "
4024                         + userHandle);
4025             }
4026         }
4027     }
4028 
4029     @Override
getFrontActivityScreenCompatMode()4030     public int getFrontActivityScreenCompatMode() {
4031         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4032         synchronized (this) {
4033             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4034         }
4035     }
4036 
4037     @Override
setFrontActivityScreenCompatMode(int mode)4038     public void setFrontActivityScreenCompatMode(int mode) {
4039         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4040                 "setFrontActivityScreenCompatMode");
4041         synchronized (this) {
4042             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4043         }
4044     }
4045 
4046     @Override
getPackageScreenCompatMode(String packageName)4047     public int getPackageScreenCompatMode(String packageName) {
4048         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4049         synchronized (this) {
4050             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4051         }
4052     }
4053 
4054     @Override
setPackageScreenCompatMode(String packageName, int mode)4055     public void setPackageScreenCompatMode(String packageName, int mode) {
4056         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4057                 "setPackageScreenCompatMode");
4058         synchronized (this) {
4059             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4060         }
4061     }
4062 
4063     @Override
getPackageAskScreenCompat(String packageName)4064     public boolean getPackageAskScreenCompat(String packageName) {
4065         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4066         synchronized (this) {
4067             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4068         }
4069     }
4070 
4071     @Override
setPackageAskScreenCompat(String packageName, boolean ask)4072     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4073         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4074                 "setPackageAskScreenCompat");
4075         synchronized (this) {
4076             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4077         }
4078     }
4079 
hasUsageStatsPermission(String callingPackage)4080     private boolean hasUsageStatsPermission(String callingPackage) {
4081         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4082                 Binder.getCallingUid(), callingPackage);
4083         if (mode == AppOpsManager.MODE_DEFAULT) {
4084             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4085                     == PackageManager.PERMISSION_GRANTED;
4086         }
4087         return mode == AppOpsManager.MODE_ALLOWED;
4088     }
4089 
4090     @Override
getPackageProcessState(String packageName, String callingPackage)4091     public int getPackageProcessState(String packageName, String callingPackage) {
4092         if (!hasUsageStatsPermission(callingPackage)) {
4093             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4094                     "getPackageProcessState");
4095         }
4096 
4097         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4098         synchronized (this) {
4099             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4100                 final ProcessRecord proc = mLruProcesses.get(i);
4101                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4102                         || procState > proc.setProcState) {
4103                     boolean found = false;
4104                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4105                         if (proc.pkgList.keyAt(j).equals(packageName)) {
4106                             procState = proc.setProcState;
4107                             found = true;
4108                         }
4109                     }
4110                     if (proc.pkgDeps != null && !found) {
4111                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4112                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4113                                 procState = proc.setProcState;
4114                                 break;
4115                             }
4116                         }
4117                     }
4118                 }
4119             }
4120         }
4121         return procState;
4122     }
4123 
4124     @Override
setProcessMemoryTrimLevel(String process, int userId, int level)4125     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4126         synchronized (this) {
4127             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4128             if (app == null) {
4129                 return false;
4130             }
4131             if (app.trimMemoryLevel < level && app.thread != null &&
4132                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4133                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4134                 try {
4135                     app.thread.scheduleTrimMemory(level);
4136                     app.trimMemoryLevel = level;
4137                     return true;
4138                 } catch (RemoteException e) {
4139                     // Fallthrough to failure case.
4140                 }
4141             }
4142         }
4143         return false;
4144     }
4145 
dispatchProcessesChanged()4146     private void dispatchProcessesChanged() {
4147         int N;
4148         synchronized (this) {
4149             N = mPendingProcessChanges.size();
4150             if (mActiveProcessChanges.length < N) {
4151                 mActiveProcessChanges = new ProcessChangeItem[N];
4152             }
4153             mPendingProcessChanges.toArray(mActiveProcessChanges);
4154             mPendingProcessChanges.clear();
4155             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4156                     "*** Delivering " + N + " process changes");
4157         }
4158 
4159         int i = mProcessObservers.beginBroadcast();
4160         while (i > 0) {
4161             i--;
4162             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4163             if (observer != null) {
4164                 try {
4165                     for (int j=0; j<N; j++) {
4166                         ProcessChangeItem item = mActiveProcessChanges[j];
4167                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4168                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4169                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4170                                     + item.uid + ": " + item.foregroundActivities);
4171                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4172                                     item.foregroundActivities);
4173                         }
4174                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4175                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4176                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4177                                     + ": " + item.processState);
4178                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4179                         }
4180                     }
4181                 } catch (RemoteException e) {
4182                 }
4183             }
4184         }
4185         mProcessObservers.finishBroadcast();
4186 
4187         synchronized (this) {
4188             for (int j=0; j<N; j++) {
4189                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4190             }
4191         }
4192     }
4193 
dispatchProcessDied(int pid, int uid)4194     private void dispatchProcessDied(int pid, int uid) {
4195         int i = mProcessObservers.beginBroadcast();
4196         while (i > 0) {
4197             i--;
4198             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4199             if (observer != null) {
4200                 try {
4201                     observer.onProcessDied(pid, uid);
4202                 } catch (RemoteException e) {
4203                 }
4204             }
4205         }
4206         mProcessObservers.finishBroadcast();
4207     }
4208 
dispatchUidsChanged()4209     private void dispatchUidsChanged() {
4210         int N;
4211         synchronized (this) {
4212             N = mPendingUidChanges.size();
4213             if (mActiveUidChanges.length < N) {
4214                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4215             }
4216             for (int i=0; i<N; i++) {
4217                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4218                 mActiveUidChanges[i] = change;
4219                 if (change.uidRecord != null) {
4220                     change.uidRecord.pendingChange = null;
4221                     change.uidRecord = null;
4222                 }
4223             }
4224             mPendingUidChanges.clear();
4225             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4226                     "*** Delivering " + N + " uid changes");
4227         }
4228 
4229         if (mLocalPowerManager != null) {
4230             for (int j=0; j<N; j++) {
4231                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4232                 if (item.change == UidRecord.CHANGE_GONE
4233                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4234                     mLocalPowerManager.uidGone(item.uid);
4235                 } else {
4236                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4237                 }
4238             }
4239         }
4240 
4241         int i = mUidObservers.beginBroadcast();
4242         while (i > 0) {
4243             i--;
4244             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4245             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4246             if (observer != null) {
4247                 try {
4248                     for (int j=0; j<N; j++) {
4249                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4250                         final int change = item.change;
4251                         UidRecord validateUid = null;
4252                         if (VALIDATE_UID_STATES && i == 0) {
4253                             validateUid = mValidateUids.get(item.uid);
4254                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4255                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4256                                 validateUid = new UidRecord(item.uid);
4257                                 mValidateUids.put(item.uid, validateUid);
4258                             }
4259                         }
4260                         if (change == UidRecord.CHANGE_IDLE
4261                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4262                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4263                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4264                                         "UID idle uid=" + item.uid);
4265                                 observer.onUidIdle(item.uid);
4266                             }
4267                             if (VALIDATE_UID_STATES && i == 0) {
4268                                 if (validateUid != null) {
4269                                     validateUid.idle = true;
4270                                 }
4271                             }
4272                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4273                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4274                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4275                                         "UID active uid=" + item.uid);
4276                                 observer.onUidActive(item.uid);
4277                             }
4278                             if (VALIDATE_UID_STATES && i == 0) {
4279                                 validateUid.idle = false;
4280                             }
4281                         }
4282                         if (change == UidRecord.CHANGE_GONE
4283                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4284                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4285                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4286                                         "UID gone uid=" + item.uid);
4287                                 observer.onUidGone(item.uid);
4288                             }
4289                             if (VALIDATE_UID_STATES && i == 0) {
4290                                 if (validateUid != null) {
4291                                     mValidateUids.remove(item.uid);
4292                                 }
4293                             }
4294                         } else {
4295                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4296                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4297                                         "UID CHANGED uid=" + item.uid
4298                                                 + ": " + item.processState);
4299                                 observer.onUidStateChanged(item.uid, item.processState);
4300                             }
4301                             if (VALIDATE_UID_STATES && i == 0) {
4302                                 validateUid.curProcState = validateUid.setProcState
4303                                         = item.processState;
4304                             }
4305                         }
4306                     }
4307                 } catch (RemoteException e) {
4308                 }
4309             }
4310         }
4311         mUidObservers.finishBroadcast();
4312 
4313         synchronized (this) {
4314             for (int j=0; j<N; j++) {
4315                 mAvailUidChanges.add(mActiveUidChanges[j]);
4316             }
4317         }
4318     }
4319 
4320     @Override
startActivity(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions)4321     public final int startActivity(IApplicationThread caller, String callingPackage,
4322             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4323             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4324         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4325                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4326                 UserHandle.getCallingUserId());
4327     }
4328 
startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container)4329     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4330         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4331         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4332                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4333                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4334 
4335         // TODO: Switch to user app stacks here.
4336         String mimeType = intent.getType();
4337         final Uri data = intent.getData();
4338         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4339             mimeType = getProviderMimeType(data, userId);
4340         }
4341         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4342 
4343         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4344         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4345                 null, 0, 0, null, null, null, null, false, userId, container, null);
4346     }
4347 
4348     @Override
startActivityAsUser(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId)4349     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4350             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4351             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4352         enforceNotIsolatedCaller("startActivity");
4353         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4354                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4355         // TODO: Switch to user app stacks here.
4356         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4357                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4358                 profilerInfo, null, null, bOptions, false, userId, null, null);
4359     }
4360 
4361     @Override
startActivityAsCaller(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity, int userId)4362     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4363             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4364             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4365             int userId) {
4366 
4367         // This is very dangerous -- it allows you to perform a start activity (including
4368         // permission grants) as any app that may launch one of your own activities.  So
4369         // we will only allow this to be done from activities that are part of the core framework,
4370         // and then only when they are running as the system.
4371         final ActivityRecord sourceRecord;
4372         final int targetUid;
4373         final String targetPackage;
4374         synchronized (this) {
4375             if (resultTo == null) {
4376                 throw new SecurityException("Must be called from an activity");
4377             }
4378             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4379             if (sourceRecord == null) {
4380                 throw new SecurityException("Called with bad activity token: " + resultTo);
4381             }
4382             if (!sourceRecord.info.packageName.equals("android")) {
4383                 throw new SecurityException(
4384                         "Must be called from an activity that is declared in the android package");
4385             }
4386             if (sourceRecord.app == null) {
4387                 throw new SecurityException("Called without a process attached to activity");
4388             }
4389             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4390                 // This is still okay, as long as this activity is running under the
4391                 // uid of the original calling activity.
4392                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4393                     throw new SecurityException(
4394                             "Calling activity in uid " + sourceRecord.app.uid
4395                                     + " must be system uid or original calling uid "
4396                                     + sourceRecord.launchedFromUid);
4397                 }
4398             }
4399             if (ignoreTargetSecurity) {
4400                 if (intent.getComponent() == null) {
4401                     throw new SecurityException(
4402                             "Component must be specified with ignoreTargetSecurity");
4403                 }
4404                 if (intent.getSelector() != null) {
4405                     throw new SecurityException(
4406                             "Selector not allowed with ignoreTargetSecurity");
4407                 }
4408             }
4409             targetUid = sourceRecord.launchedFromUid;
4410             targetPackage = sourceRecord.launchedFromPackage;
4411         }
4412 
4413         if (userId == UserHandle.USER_NULL) {
4414             userId = UserHandle.getUserId(sourceRecord.app.uid);
4415         }
4416 
4417         // TODO: Switch to user app stacks here.
4418         try {
4419             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4420                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4421                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4422             return ret;
4423         } catch (SecurityException e) {
4424             // XXX need to figure out how to propagate to original app.
4425             // A SecurityException here is generally actually a fault of the original
4426             // calling activity (such as a fairly granting permissions), so propagate it
4427             // back to them.
4428             /*
4429             StringBuilder msg = new StringBuilder();
4430             msg.append("While launching");
4431             msg.append(intent.toString());
4432             msg.append(": ");
4433             msg.append(e.getMessage());
4434             */
4435             throw e;
4436         }
4437     }
4438 
4439     @Override
startActivityAndWait(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId)4440     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4441             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4442             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4443         enforceNotIsolatedCaller("startActivityAndWait");
4444         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4445                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4446         WaitResult res = new WaitResult();
4447         // TODO: Switch to user app stacks here.
4448         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4449                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4450                 bOptions, false, userId, null, null);
4451         return res;
4452     }
4453 
4454     @Override
startActivityWithConfig(IApplicationThread caller, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Configuration config, Bundle bOptions, int userId)4455     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4456             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4457             int startFlags, Configuration config, Bundle bOptions, int userId) {
4458         enforceNotIsolatedCaller("startActivityWithConfig");
4459         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4460                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4461         // TODO: Switch to user app stacks here.
4462         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4463                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4464                 null, null, config, bOptions, false, userId, null, null);
4465         return ret;
4466     }
4467 
4468     @Override
startActivityIntentSender(IApplicationThread caller, IntentSender intent, Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int flagsMask, int flagsValues, Bundle bOptions)4469     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4470             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4471             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4472             throws TransactionTooLargeException {
4473         enforceNotIsolatedCaller("startActivityIntentSender");
4474         // Refuse possible leaked file descriptors
4475         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4476             throw new IllegalArgumentException("File descriptors passed in Intent");
4477         }
4478 
4479         IIntentSender sender = intent.getTarget();
4480         if (!(sender instanceof PendingIntentRecord)) {
4481             throw new IllegalArgumentException("Bad PendingIntent object");
4482         }
4483 
4484         PendingIntentRecord pir = (PendingIntentRecord)sender;
4485 
4486         synchronized (this) {
4487             // If this is coming from the currently resumed activity, it is
4488             // effectively saying that app switches are allowed at this point.
4489             final ActivityStack stack = getFocusedStack();
4490             if (stack.mResumedActivity != null &&
4491                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4492                 mAppSwitchesAllowedTime = 0;
4493             }
4494         }
4495         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4496                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4497         return ret;
4498     }
4499 
4500     @Override
startVoiceActivity(String callingPackage, int callingPid, int callingUid, Intent intent, String resolvedType, IVoiceInteractionSession session, IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId)4501     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4502             Intent intent, String resolvedType, IVoiceInteractionSession session,
4503             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4504             Bundle bOptions, int userId) {
4505         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4506                 != PackageManager.PERMISSION_GRANTED) {
4507             String msg = "Permission Denial: startVoiceActivity() from pid="
4508                     + Binder.getCallingPid()
4509                     + ", uid=" + Binder.getCallingUid()
4510                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4511             Slog.w(TAG, msg);
4512             throw new SecurityException(msg);
4513         }
4514         if (session == null || interactor == null) {
4515             throw new NullPointerException("null session or interactor");
4516         }
4517         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4518                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4519         // TODO: Switch to user app stacks here.
4520         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4521                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4522                 null, bOptions, false, userId, null, null);
4523     }
4524 
4525     @Override
startLocalVoiceInteraction(IBinder callingActivity, Bundle options)4526     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4527             throws RemoteException {
4528         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4529         synchronized (this) {
4530             ActivityRecord activity = getFocusedStack().topActivity();
4531             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4532                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4533             }
4534             if (mRunningVoice != null || activity.task.voiceSession != null
4535                     || activity.voiceSession != null) {
4536                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4537                 return;
4538             }
4539             if (activity.pendingVoiceInteractionStart) {
4540                 Slog.w(TAG, "Pending start of voice interaction already.");
4541                 return;
4542             }
4543             activity.pendingVoiceInteractionStart = true;
4544         }
4545         LocalServices.getService(VoiceInteractionManagerInternal.class)
4546                 .startLocalVoiceInteraction(callingActivity, options);
4547     }
4548 
4549     @Override
stopLocalVoiceInteraction(IBinder callingActivity)4550     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4551         LocalServices.getService(VoiceInteractionManagerInternal.class)
4552                 .stopLocalVoiceInteraction(callingActivity);
4553     }
4554 
4555     @Override
supportsLocalVoiceInteraction()4556     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4557         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4558                 .supportsLocalVoiceInteraction();
4559     }
4560 
onLocalVoiceInteractionStartedLocked(IBinder activity, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor)4561     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4562             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4563         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4564         if (activityToCallback == null) return;
4565         activityToCallback.setVoiceSessionLocked(voiceSession);
4566 
4567         // Inform the activity
4568         try {
4569             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4570                     voiceInteractor);
4571             long token = Binder.clearCallingIdentity();
4572             try {
4573                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4574             } finally {
4575                 Binder.restoreCallingIdentity(token);
4576             }
4577             // TODO: VI Should we cache the activity so that it's easier to find later
4578             // rather than scan through all the stacks and activities?
4579         } catch (RemoteException re) {
4580             activityToCallback.clearVoiceSessionLocked();
4581             // TODO: VI Should this terminate the voice session?
4582         }
4583     }
4584 
4585     @Override
setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake)4586     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4587         synchronized (this) {
4588             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4589                 if (keepAwake) {
4590                     mVoiceWakeLock.acquire();
4591                 } else {
4592                     mVoiceWakeLock.release();
4593                 }
4594             }
4595         }
4596     }
4597 
4598     @Override
startNextMatchingActivity(IBinder callingActivity, Intent intent, Bundle bOptions)4599     public boolean startNextMatchingActivity(IBinder callingActivity,
4600             Intent intent, Bundle bOptions) {
4601         // Refuse possible leaked file descriptors
4602         if (intent != null && intent.hasFileDescriptors() == true) {
4603             throw new IllegalArgumentException("File descriptors passed in Intent");
4604         }
4605         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4606 
4607         synchronized (this) {
4608             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4609             if (r == null) {
4610                 ActivityOptions.abort(options);
4611                 return false;
4612             }
4613             if (r.app == null || r.app.thread == null) {
4614                 // The caller is not running...  d'oh!
4615                 ActivityOptions.abort(options);
4616                 return false;
4617             }
4618             intent = new Intent(intent);
4619             // The caller is not allowed to change the data.
4620             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4621             // And we are resetting to find the next component...
4622             intent.setComponent(null);
4623 
4624             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4625 
4626             ActivityInfo aInfo = null;
4627             try {
4628                 List<ResolveInfo> resolves =
4629                     AppGlobals.getPackageManager().queryIntentActivities(
4630                             intent, r.resolvedType,
4631                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4632                             UserHandle.getCallingUserId()).getList();
4633 
4634                 // Look for the original activity in the list...
4635                 final int N = resolves != null ? resolves.size() : 0;
4636                 for (int i=0; i<N; i++) {
4637                     ResolveInfo rInfo = resolves.get(i);
4638                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4639                             && rInfo.activityInfo.name.equals(r.info.name)) {
4640                         // We found the current one...  the next matching is
4641                         // after it.
4642                         i++;
4643                         if (i<N) {
4644                             aInfo = resolves.get(i).activityInfo;
4645                         }
4646                         if (debug) {
4647                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4648                                     + "/" + r.info.name);
4649                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4650                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4651                         }
4652                         break;
4653                     }
4654                 }
4655             } catch (RemoteException e) {
4656             }
4657 
4658             if (aInfo == null) {
4659                 // Nobody who is next!
4660                 ActivityOptions.abort(options);
4661                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4662                 return false;
4663             }
4664 
4665             intent.setComponent(new ComponentName(
4666                     aInfo.applicationInfo.packageName, aInfo.name));
4667             intent.setFlags(intent.getFlags()&~(
4668                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4669                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4670                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4671                     Intent.FLAG_ACTIVITY_NEW_TASK));
4672 
4673             // Okay now we need to start the new activity, replacing the
4674             // currently running activity.  This is a little tricky because
4675             // we want to start the new one as if the current one is finished,
4676             // but not finish the current one first so that there is no flicker.
4677             // And thus...
4678             final boolean wasFinishing = r.finishing;
4679             r.finishing = true;
4680 
4681             // Propagate reply information over to the new activity.
4682             final ActivityRecord resultTo = r.resultTo;
4683             final String resultWho = r.resultWho;
4684             final int requestCode = r.requestCode;
4685             r.resultTo = null;
4686             if (resultTo != null) {
4687                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4688             }
4689 
4690             final long origId = Binder.clearCallingIdentity();
4691             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4692                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4693                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4694                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4695                     false, false, null, null, null);
4696             Binder.restoreCallingIdentity(origId);
4697 
4698             r.finishing = wasFinishing;
4699             if (res != ActivityManager.START_SUCCESS) {
4700                 return false;
4701             }
4702             return true;
4703         }
4704     }
4705 
4706     @Override
startActivityFromRecents(int taskId, Bundle bOptions)4707     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4708         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4709             String msg = "Permission Denial: startActivityFromRecents called without " +
4710                     START_TASKS_FROM_RECENTS;
4711             Slog.w(TAG, msg);
4712             throw new SecurityException(msg);
4713         }
4714         final long origId = Binder.clearCallingIdentity();
4715         try {
4716             synchronized (this) {
4717                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4718             }
4719         } finally {
4720             Binder.restoreCallingIdentity(origId);
4721         }
4722     }
4723 
startActivityInPackage(int uid, String callingPackage, Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId, IActivityContainer container, TaskRecord inTask)4724     final int startActivityInPackage(int uid, String callingPackage,
4725             Intent intent, String resolvedType, IBinder resultTo,
4726             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4727             IActivityContainer container, TaskRecord inTask) {
4728 
4729         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4730                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4731 
4732         // TODO: Switch to user app stacks here.
4733         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4734                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4735                 null, null, null, bOptions, false, userId, container, inTask);
4736         return ret;
4737     }
4738 
4739     @Override
startActivities(IApplicationThread caller, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions, int userId)4740     public final int startActivities(IApplicationThread caller, String callingPackage,
4741             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4742             int userId) {
4743         enforceNotIsolatedCaller("startActivities");
4744         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4745                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4746         // TODO: Switch to user app stacks here.
4747         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4748                 resolvedTypes, resultTo, bOptions, userId);
4749         return ret;
4750     }
4751 
startActivitiesInPackage(int uid, String callingPackage, Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions, int userId)4752     final int startActivitiesInPackage(int uid, String callingPackage,
4753             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4754             Bundle bOptions, int userId) {
4755 
4756         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4757                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4758         // TODO: Switch to user app stacks here.
4759         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4760                 resultTo, bOptions, userId);
4761         return ret;
4762     }
4763 
4764     @Override
reportActivityFullyDrawn(IBinder token)4765     public void reportActivityFullyDrawn(IBinder token) {
4766         synchronized (this) {
4767             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4768             if (r == null) {
4769                 return;
4770             }
4771             r.reportFullyDrawnLocked();
4772         }
4773     }
4774 
4775     @Override
setRequestedOrientation(IBinder token, int requestedOrientation)4776     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4777         synchronized (this) {
4778             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4779             if (r == null) {
4780                 return;
4781             }
4782             TaskRecord task = r.task;
4783             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4784                 // Fixed screen orientation isn't supported when activities aren't in full screen
4785                 // mode.
4786                 return;
4787             }
4788             final long origId = Binder.clearCallingIdentity();
4789             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4790             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4791                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4792             if (config != null) {
4793                 r.frozenBeforeDestroy = true;
4794                 if (!updateConfigurationLocked(config, r, false)) {
4795                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4796                 }
4797             }
4798             Binder.restoreCallingIdentity(origId);
4799         }
4800     }
4801 
4802     @Override
getRequestedOrientation(IBinder token)4803     public int getRequestedOrientation(IBinder token) {
4804         synchronized (this) {
4805             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4806             if (r == null) {
4807                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4808             }
4809             return mWindowManager.getAppOrientation(r.appToken);
4810         }
4811     }
4812 
4813     /**
4814      * This is the internal entry point for handling Activity.finish().
4815      *
4816      * @param token The Binder token referencing the Activity we want to finish.
4817      * @param resultCode Result code, if any, from this Activity.
4818      * @param resultData Result data (Intent), if any, from this Activity.
4819      * @param finishTask Whether to finish the task associated with this Activity.
4820      *
4821      * @return Returns true if the activity successfully finished, or false if it is still running.
4822      */
4823     @Override
finishActivity(IBinder token, int resultCode, Intent resultData, int finishTask)4824     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4825             int finishTask) {
4826         // Refuse possible leaked file descriptors
4827         if (resultData != null && resultData.hasFileDescriptors() == true) {
4828             throw new IllegalArgumentException("File descriptors passed in Intent");
4829         }
4830 
4831         synchronized(this) {
4832             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4833             if (r == null) {
4834                 return true;
4835             }
4836             // Keep track of the root activity of the task before we finish it
4837             TaskRecord tr = r.task;
4838             ActivityRecord rootR = tr.getRootActivity();
4839             if (rootR == null) {
4840                 Slog.w(TAG, "Finishing task with all activities already finished");
4841             }
4842             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4843             // finish.
4844             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4845                     mStackSupervisor.isLastLockedTask(tr)) {
4846                 Slog.i(TAG, "Not finishing task in lock task mode");
4847                 mStackSupervisor.showLockTaskToast();
4848                 return false;
4849             }
4850             if (mController != null) {
4851                 // Find the first activity that is not finishing.
4852                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4853                 if (next != null) {
4854                     // ask watcher if this is allowed
4855                     boolean resumeOK = true;
4856                     try {
4857                         resumeOK = mController.activityResuming(next.packageName);
4858                     } catch (RemoteException e) {
4859                         mController = null;
4860                         Watchdog.getInstance().setActivityController(null);
4861                     }
4862 
4863                     if (!resumeOK) {
4864                         Slog.i(TAG, "Not finishing activity because controller resumed");
4865                         return false;
4866                     }
4867                 }
4868             }
4869             final long origId = Binder.clearCallingIdentity();
4870             try {
4871                 boolean res;
4872                 final boolean finishWithRootActivity =
4873                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4874                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4875                         || (finishWithRootActivity && r == rootR)) {
4876                     // If requested, remove the task that is associated to this activity only if it
4877                     // was the root activity in the task. The result code and data is ignored
4878                     // because we don't support returning them across task boundaries. Also, to
4879                     // keep backwards compatibility we remove the task from recents when finishing
4880                     // task with root activity.
4881                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4882                     if (!res) {
4883                         Slog.i(TAG, "Removing task failed to finish activity");
4884                     }
4885                 } else {
4886                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4887                             resultData, "app-request", true);
4888                     if (!res) {
4889                         Slog.i(TAG, "Failed to finish by app-request");
4890                     }
4891                 }
4892                 return res;
4893             } finally {
4894                 Binder.restoreCallingIdentity(origId);
4895             }
4896         }
4897     }
4898 
4899     @Override
finishHeavyWeightApp()4900     public final void finishHeavyWeightApp() {
4901         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4902                 != PackageManager.PERMISSION_GRANTED) {
4903             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4904                     + Binder.getCallingPid()
4905                     + ", uid=" + Binder.getCallingUid()
4906                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4907             Slog.w(TAG, msg);
4908             throw new SecurityException(msg);
4909         }
4910 
4911         synchronized(this) {
4912             if (mHeavyWeightProcess == null) {
4913                 return;
4914             }
4915 
4916             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4917             for (int i = 0; i < activities.size(); i++) {
4918                 ActivityRecord r = activities.get(i);
4919                 if (!r.finishing && r.isInStackLocked()) {
4920                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4921                             null, "finish-heavy", true);
4922                 }
4923             }
4924 
4925             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4926                     mHeavyWeightProcess.userId, 0));
4927             mHeavyWeightProcess = null;
4928         }
4929     }
4930 
4931     @Override
crashApplication(int uid, int initialPid, String packageName, String message)4932     public void crashApplication(int uid, int initialPid, String packageName,
4933             String message) {
4934         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4935                 != PackageManager.PERMISSION_GRANTED) {
4936             String msg = "Permission Denial: crashApplication() from pid="
4937                     + Binder.getCallingPid()
4938                     + ", uid=" + Binder.getCallingUid()
4939                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4940             Slog.w(TAG, msg);
4941             throw new SecurityException(msg);
4942         }
4943 
4944         synchronized(this) {
4945             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4946         }
4947     }
4948 
4949     @Override
finishSubActivity(IBinder token, String resultWho, int requestCode)4950     public final void finishSubActivity(IBinder token, String resultWho,
4951             int requestCode) {
4952         synchronized(this) {
4953             final long origId = Binder.clearCallingIdentity();
4954             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4955             if (r != null) {
4956                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4957             }
4958             Binder.restoreCallingIdentity(origId);
4959         }
4960     }
4961 
4962     @Override
finishActivityAffinity(IBinder token)4963     public boolean finishActivityAffinity(IBinder token) {
4964         synchronized(this) {
4965             final long origId = Binder.clearCallingIdentity();
4966             try {
4967                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4968                 if (r == null) {
4969                     return false;
4970                 }
4971 
4972                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4973                 // can finish.
4974                 final TaskRecord task = r.task;
4975                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4976                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4977                     mStackSupervisor.showLockTaskToast();
4978                     return false;
4979                 }
4980                 return task.stack.finishActivityAffinityLocked(r);
4981             } finally {
4982                 Binder.restoreCallingIdentity(origId);
4983             }
4984         }
4985     }
4986 
4987     @Override
finishVoiceTask(IVoiceInteractionSession session)4988     public void finishVoiceTask(IVoiceInteractionSession session) {
4989         synchronized (this) {
4990             final long origId = Binder.clearCallingIdentity();
4991             try {
4992                 // TODO: VI Consider treating local voice interactions and voice tasks
4993                 // differently here
4994                 mStackSupervisor.finishVoiceTask(session);
4995             } finally {
4996                 Binder.restoreCallingIdentity(origId);
4997             }
4998         }
4999 
5000     }
5001 
5002     @Override
releaseActivityInstance(IBinder token)5003     public boolean releaseActivityInstance(IBinder token) {
5004         synchronized(this) {
5005             final long origId = Binder.clearCallingIdentity();
5006             try {
5007                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5008                 if (r == null) {
5009                     return false;
5010                 }
5011                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5012             } finally {
5013                 Binder.restoreCallingIdentity(origId);
5014             }
5015         }
5016     }
5017 
5018     @Override
releaseSomeActivities(IApplicationThread appInt)5019     public void releaseSomeActivities(IApplicationThread appInt) {
5020         synchronized(this) {
5021             final long origId = Binder.clearCallingIdentity();
5022             try {
5023                 ProcessRecord app = getRecordForAppLocked(appInt);
5024                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5025             } finally {
5026                 Binder.restoreCallingIdentity(origId);
5027             }
5028         }
5029     }
5030 
5031     @Override
willActivityBeVisible(IBinder token)5032     public boolean willActivityBeVisible(IBinder token) {
5033         synchronized(this) {
5034             ActivityStack stack = ActivityRecord.getStackLocked(token);
5035             if (stack != null) {
5036                 return stack.willActivityBeVisibleLocked(token);
5037             }
5038             return false;
5039         }
5040     }
5041 
5042     @Override
overridePendingTransition(IBinder token, String packageName, int enterAnim, int exitAnim)5043     public void overridePendingTransition(IBinder token, String packageName,
5044             int enterAnim, int exitAnim) {
5045         synchronized(this) {
5046             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5047             if (self == null) {
5048                 return;
5049             }
5050 
5051             final long origId = Binder.clearCallingIdentity();
5052 
5053             if (self.state == ActivityState.RESUMED
5054                     || self.state == ActivityState.PAUSING) {
5055                 mWindowManager.overridePendingAppTransition(packageName,
5056                         enterAnim, exitAnim, null);
5057             }
5058 
5059             Binder.restoreCallingIdentity(origId);
5060         }
5061     }
5062 
5063     /**
5064      * Main function for removing an existing process from the activity manager
5065      * as a result of that process going away.  Clears out all connections
5066      * to the process.
5067      */
handleAppDiedLocked(ProcessRecord app, boolean restarting, boolean allowRestart)5068     private final void handleAppDiedLocked(ProcessRecord app,
5069             boolean restarting, boolean allowRestart) {
5070         int pid = app.pid;
5071         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5072                 false /*replacingPid*/);
5073         if (!kept && !restarting) {
5074             removeLruProcessLocked(app);
5075             if (pid > 0) {
5076                 ProcessList.remove(pid);
5077             }
5078         }
5079 
5080         if (mProfileProc == app) {
5081             clearProfilerLocked();
5082         }
5083 
5084         // Remove this application's activities from active lists.
5085         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5086 
5087         app.activities.clear();
5088 
5089         if (app.instrumentationClass != null) {
5090             Slog.w(TAG, "Crash of app " + app.processName
5091                   + " running instrumentation " + app.instrumentationClass);
5092             Bundle info = new Bundle();
5093             info.putString("shortMsg", "Process crashed.");
5094             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5095         }
5096 
5097         if (!restarting && hasVisibleActivities
5098                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5099             // If there was nothing to resume, and we are not already restarting this process, but
5100             // there is a visible activity that is hosted by the process...  then make sure all
5101             // visible activities are running, taking care of restarting this process.
5102             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5103         }
5104     }
5105 
getLRURecordIndexForAppLocked(IApplicationThread thread)5106     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5107         IBinder threadBinder = thread.asBinder();
5108         // Find the application record.
5109         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5110             ProcessRecord rec = mLruProcesses.get(i);
5111             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5112                 return i;
5113             }
5114         }
5115         return -1;
5116     }
5117 
getRecordForAppLocked( IApplicationThread thread)5118     final ProcessRecord getRecordForAppLocked(
5119             IApplicationThread thread) {
5120         if (thread == null) {
5121             return null;
5122         }
5123 
5124         int appIndex = getLRURecordIndexForAppLocked(thread);
5125         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5126     }
5127 
doLowMemReportIfNeededLocked(ProcessRecord dyingProc)5128     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5129         // If there are no longer any background processes running,
5130         // and the app that died was not running instrumentation,
5131         // then tell everyone we are now low on memory.
5132         boolean haveBg = false;
5133         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5134             ProcessRecord rec = mLruProcesses.get(i);
5135             if (rec.thread != null
5136                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5137                 haveBg = true;
5138                 break;
5139             }
5140         }
5141 
5142         if (!haveBg) {
5143             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5144             if (doReport) {
5145                 long now = SystemClock.uptimeMillis();
5146                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5147                     doReport = false;
5148                 } else {
5149                     mLastMemUsageReportTime = now;
5150                 }
5151             }
5152             final ArrayList<ProcessMemInfo> memInfos
5153                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5154             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5155             long now = SystemClock.uptimeMillis();
5156             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5157                 ProcessRecord rec = mLruProcesses.get(i);
5158                 if (rec == dyingProc || rec.thread == null) {
5159                     continue;
5160                 }
5161                 if (doReport) {
5162                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5163                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5164                 }
5165                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5166                     // The low memory report is overriding any current
5167                     // state for a GC request.  Make sure to do
5168                     // heavy/important/visible/foreground processes first.
5169                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5170                         rec.lastRequestedGc = 0;
5171                     } else {
5172                         rec.lastRequestedGc = rec.lastLowMemory;
5173                     }
5174                     rec.reportLowMemory = true;
5175                     rec.lastLowMemory = now;
5176                     mProcessesToGc.remove(rec);
5177                     addProcessToGcListLocked(rec);
5178                 }
5179             }
5180             if (doReport) {
5181                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5182                 mHandler.sendMessage(msg);
5183             }
5184             scheduleAppGcsLocked();
5185         }
5186     }
5187 
appDiedLocked(ProcessRecord app)5188     final void appDiedLocked(ProcessRecord app) {
5189        appDiedLocked(app, app.pid, app.thread, false);
5190     }
5191 
appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread, boolean fromBinderDied)5192     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5193             boolean fromBinderDied) {
5194         // First check if this ProcessRecord is actually active for the pid.
5195         synchronized (mPidsSelfLocked) {
5196             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5197             if (curProc != app) {
5198                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5199                 return;
5200             }
5201         }
5202 
5203         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5204         synchronized (stats) {
5205             stats.noteProcessDiedLocked(app.info.uid, pid);
5206         }
5207 
5208         if (!app.killed) {
5209             if (!fromBinderDied) {
5210                 Process.killProcessQuiet(pid);
5211             }
5212             killProcessGroup(app.uid, pid);
5213             app.killed = true;
5214         }
5215 
5216         // Clean up already done if the process has been re-started.
5217         if (app.pid == pid && app.thread != null &&
5218                 app.thread.asBinder() == thread.asBinder()) {
5219             boolean doLowMem = app.instrumentationClass == null;
5220             boolean doOomAdj = doLowMem;
5221             if (!app.killedByAm) {
5222                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5223                         + ") has died");
5224                 mAllowLowerMemLevel = true;
5225             } else {
5226                 // Note that we always want to do oom adj to update our state with the
5227                 // new number of procs.
5228                 mAllowLowerMemLevel = false;
5229                 doLowMem = false;
5230             }
5231             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5232             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5233                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5234             handleAppDiedLocked(app, false, true);
5235 
5236             if (doOomAdj) {
5237                 updateOomAdjLocked();
5238             }
5239             if (doLowMem) {
5240                 doLowMemReportIfNeededLocked(app);
5241             }
5242         } else if (app.pid != pid) {
5243             // A new process has already been started.
5244             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5245                     + ") has died and restarted (pid " + app.pid + ").");
5246             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5247         } else if (DEBUG_PROCESSES) {
5248             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5249                     + thread.asBinder());
5250         }
5251     }
5252 
5253     /**
5254      * If a stack trace dump file is configured, dump process stack traces.
5255      * @param clearTraces causes the dump file to be erased prior to the new
5256      *    traces being written, if true; when false, the new traces will be
5257      *    appended to any existing file content.
5258      * @param firstPids of dalvik VM processes to dump stack traces for first
5259      * @param lastPids of dalvik VM processes to dump stack traces for last
5260      * @param nativeProcs optional list of native process names to dump stack crawls
5261      * @return file containing stack traces, or null if no dump file is configured
5262      */
dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids, ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs)5263     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5264             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5265         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5266         if (tracesPath == null || tracesPath.length() == 0) {
5267             return null;
5268         }
5269 
5270         File tracesFile = new File(tracesPath);
5271         try {
5272             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5273             tracesFile.createNewFile();
5274             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5275         } catch (IOException e) {
5276             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5277             return null;
5278         }
5279 
5280         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5281         return tracesFile;
5282     }
5283 
dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids, ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs)5284     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5285             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5286         // Use a FileObserver to detect when traces finish writing.
5287         // The order of traces is considered important to maintain for legibility.
5288         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5289             @Override
5290             public synchronized void onEvent(int event, String path) { notify(); }
5291         };
5292 
5293         try {
5294             observer.startWatching();
5295 
5296             // First collect all of the stacks of the most important pids.
5297             if (firstPids != null) {
5298                 try {
5299                     int num = firstPids.size();
5300                     for (int i = 0; i < num; i++) {
5301                         synchronized (observer) {
5302                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5303                                     + firstPids.get(i));
5304                             final long sime = SystemClock.elapsedRealtime();
5305                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5306                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5307                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5308                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5309                         }
5310                     }
5311                 } catch (InterruptedException e) {
5312                     Slog.wtf(TAG, e);
5313                 }
5314             }
5315 
5316             // Next collect the stacks of the native pids
5317             if (nativeProcs != null) {
5318                 int[] pids = Process.getPidsForCommands(nativeProcs);
5319                 if (pids != null) {
5320                     for (int pid : pids) {
5321                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5322                         final long sime = SystemClock.elapsedRealtime();
5323                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5324                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5325                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5326                     }
5327                 }
5328             }
5329 
5330             // Lastly, measure CPU usage.
5331             if (processCpuTracker != null) {
5332                 processCpuTracker.init();
5333                 System.gc();
5334                 processCpuTracker.update();
5335                 try {
5336                     synchronized (processCpuTracker) {
5337                         processCpuTracker.wait(500); // measure over 1/2 second.
5338                     }
5339                 } catch (InterruptedException e) {
5340                 }
5341                 processCpuTracker.update();
5342 
5343                 // We'll take the stack crawls of just the top apps using CPU.
5344                 final int N = processCpuTracker.countWorkingStats();
5345                 int numProcs = 0;
5346                 for (int i=0; i<N && numProcs<5; i++) {
5347                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5348                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5349                         numProcs++;
5350                         try {
5351                             synchronized (observer) {
5352                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5353                                         + stats.pid);
5354                                 final long stime = SystemClock.elapsedRealtime();
5355                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5356                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5357                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5358                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5359                             }
5360                         } catch (InterruptedException e) {
5361                             Slog.wtf(TAG, e);
5362                         }
5363                     } else if (DEBUG_ANR) {
5364                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5365                                 + stats.pid);
5366                     }
5367                 }
5368             }
5369         } finally {
5370             observer.stopWatching();
5371         }
5372     }
5373 
logAppTooSlow(ProcessRecord app, long startTime, String msg)5374     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5375         if (true || IS_USER_BUILD) {
5376             return;
5377         }
5378         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5379         if (tracesPath == null || tracesPath.length() == 0) {
5380             return;
5381         }
5382 
5383         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5384         StrictMode.allowThreadDiskWrites();
5385         try {
5386             final File tracesFile = new File(tracesPath);
5387             final File tracesDir = tracesFile.getParentFile();
5388             final File tracesTmp = new File(tracesDir, "__tmp__");
5389             try {
5390                 if (tracesFile.exists()) {
5391                     tracesTmp.delete();
5392                     tracesFile.renameTo(tracesTmp);
5393                 }
5394                 StringBuilder sb = new StringBuilder();
5395                 Time tobj = new Time();
5396                 tobj.set(System.currentTimeMillis());
5397                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5398                 sb.append(": ");
5399                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5400                 sb.append(" since ");
5401                 sb.append(msg);
5402                 FileOutputStream fos = new FileOutputStream(tracesFile);
5403                 fos.write(sb.toString().getBytes());
5404                 if (app == null) {
5405                     fos.write("\n*** No application process!".getBytes());
5406                 }
5407                 fos.close();
5408                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5409             } catch (IOException e) {
5410                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5411                 return;
5412             }
5413 
5414             if (app != null) {
5415                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5416                 firstPids.add(app.pid);
5417                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5418             }
5419 
5420             File lastTracesFile = null;
5421             File curTracesFile = null;
5422             for (int i=9; i>=0; i--) {
5423                 String name = String.format(Locale.US, "slow%02d.txt", i);
5424                 curTracesFile = new File(tracesDir, name);
5425                 if (curTracesFile.exists()) {
5426                     if (lastTracesFile != null) {
5427                         curTracesFile.renameTo(lastTracesFile);
5428                     } else {
5429                         curTracesFile.delete();
5430                     }
5431                 }
5432                 lastTracesFile = curTracesFile;
5433             }
5434             tracesFile.renameTo(curTracesFile);
5435             if (tracesTmp.exists()) {
5436                 tracesTmp.renameTo(tracesFile);
5437             }
5438         } finally {
5439             StrictMode.setThreadPolicy(oldPolicy);
5440         }
5441     }
5442 
showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next)5443     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5444         if (!mLaunchWarningShown) {
5445             mLaunchWarningShown = true;
5446             mUiHandler.post(new Runnable() {
5447                 @Override
5448                 public void run() {
5449                     synchronized (ActivityManagerService.this) {
5450                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5451                         d.show();
5452                         mUiHandler.postDelayed(new Runnable() {
5453                             @Override
5454                             public void run() {
5455                                 synchronized (ActivityManagerService.this) {
5456                                     d.dismiss();
5457                                     mLaunchWarningShown = false;
5458                                 }
5459                             }
5460                         }, 4000);
5461                     }
5462                 }
5463             });
5464         }
5465     }
5466 
5467     @Override
clearApplicationUserData(final String packageName, final IPackageDataObserver observer, int userId)5468     public boolean clearApplicationUserData(final String packageName,
5469             final IPackageDataObserver observer, int userId) {
5470         enforceNotIsolatedCaller("clearApplicationUserData");
5471         int uid = Binder.getCallingUid();
5472         int pid = Binder.getCallingPid();
5473         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5474                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5475 
5476 
5477         long callingId = Binder.clearCallingIdentity();
5478         try {
5479             IPackageManager pm = AppGlobals.getPackageManager();
5480             int pkgUid = -1;
5481             synchronized(this) {
5482                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5483                         userId, packageName)) {
5484                     throw new SecurityException(
5485                             "Cannot clear data for a protected package: " + packageName);
5486                 }
5487 
5488                 try {
5489                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5490                 } catch (RemoteException e) {
5491                 }
5492                 if (pkgUid == -1) {
5493                     Slog.w(TAG, "Invalid packageName: " + packageName);
5494                     if (observer != null) {
5495                         try {
5496                             observer.onRemoveCompleted(packageName, false);
5497                         } catch (RemoteException e) {
5498                             Slog.i(TAG, "Observer no longer exists.");
5499                         }
5500                     }
5501                     return false;
5502                 }
5503                 if (uid == pkgUid || checkComponentPermission(
5504                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5505                         pid, uid, -1, true)
5506                         == PackageManager.PERMISSION_GRANTED) {
5507                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5508                 } else {
5509                     throw new SecurityException("PID " + pid + " does not have permission "
5510                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5511                                     + " of package " + packageName);
5512                 }
5513 
5514                 // Remove all tasks match the cleared application package and user
5515                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5516                     final TaskRecord tr = mRecentTasks.get(i);
5517                     final String taskPackageName =
5518                             tr.getBaseIntent().getComponent().getPackageName();
5519                     if (tr.userId != userId) continue;
5520                     if (!taskPackageName.equals(packageName)) continue;
5521                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5522                 }
5523             }
5524 
5525             final int pkgUidF = pkgUid;
5526             final int userIdF = userId;
5527             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5528                 @Override
5529                 public void onRemoveCompleted(String packageName, boolean succeeded)
5530                         throws RemoteException {
5531                     synchronized (ActivityManagerService.this) {
5532                         finishForceStopPackageLocked(packageName, pkgUidF);
5533                     }
5534 
5535                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5536                             Uri.fromParts("package", packageName, null));
5537                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5538                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5539                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5540                             null, null, 0, null, null, null, null, false, false, userIdF);
5541 
5542                     if (observer != null) {
5543                         observer.onRemoveCompleted(packageName, succeeded);
5544                     }
5545                 }
5546             };
5547 
5548             try {
5549                 // Clear application user data
5550                 pm.clearApplicationUserData(packageName, localObserver, userId);
5551 
5552                 synchronized(this) {
5553                     // Remove all permissions granted from/to this package
5554                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5555                 }
5556 
5557                 // Remove all zen rules created by this package; revoke it's zen access.
5558                 INotificationManager inm = NotificationManager.getService();
5559                 inm.removeAutomaticZenRules(packageName);
5560                 inm.setNotificationPolicyAccessGranted(packageName, false);
5561 
5562             } catch (RemoteException e) {
5563             }
5564         } finally {
5565             Binder.restoreCallingIdentity(callingId);
5566         }
5567         return true;
5568     }
5569 
5570     @Override
killBackgroundProcesses(final String packageName, int userId)5571     public void killBackgroundProcesses(final String packageName, int userId) {
5572         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5573                 != PackageManager.PERMISSION_GRANTED &&
5574                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5575                         != PackageManager.PERMISSION_GRANTED) {
5576             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5577                     + Binder.getCallingPid()
5578                     + ", uid=" + Binder.getCallingUid()
5579                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5580             Slog.w(TAG, msg);
5581             throw new SecurityException(msg);
5582         }
5583 
5584         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5585                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5586         long callingId = Binder.clearCallingIdentity();
5587         try {
5588             IPackageManager pm = AppGlobals.getPackageManager();
5589             synchronized(this) {
5590                 int appId = -1;
5591                 try {
5592                     appId = UserHandle.getAppId(
5593                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5594                 } catch (RemoteException e) {
5595                 }
5596                 if (appId == -1) {
5597                     Slog.w(TAG, "Invalid packageName: " + packageName);
5598                     return;
5599                 }
5600                 killPackageProcessesLocked(packageName, appId, userId,
5601                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5602             }
5603         } finally {
5604             Binder.restoreCallingIdentity(callingId);
5605         }
5606     }
5607 
5608     @Override
killAllBackgroundProcesses()5609     public void killAllBackgroundProcesses() {
5610         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5611                 != PackageManager.PERMISSION_GRANTED) {
5612             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5613                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5614                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5615             Slog.w(TAG, msg);
5616             throw new SecurityException(msg);
5617         }
5618 
5619         final long callingId = Binder.clearCallingIdentity();
5620         try {
5621             synchronized (this) {
5622                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5623                 final int NP = mProcessNames.getMap().size();
5624                 for (int ip = 0; ip < NP; ip++) {
5625                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5626                     final int NA = apps.size();
5627                     for (int ia = 0; ia < NA; ia++) {
5628                         final ProcessRecord app = apps.valueAt(ia);
5629                         if (app.persistent) {
5630                             // We don't kill persistent processes.
5631                             continue;
5632                         }
5633                         if (app.removed) {
5634                             procs.add(app);
5635                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5636                             app.removed = true;
5637                             procs.add(app);
5638                         }
5639                     }
5640                 }
5641 
5642                 final int N = procs.size();
5643                 for (int i = 0; i < N; i++) {
5644                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5645                 }
5646 
5647                 mAllowLowerMemLevel = true;
5648 
5649                 updateOomAdjLocked();
5650                 doLowMemReportIfNeededLocked(null);
5651             }
5652         } finally {
5653             Binder.restoreCallingIdentity(callingId);
5654         }
5655     }
5656 
5657     /**
5658      * Kills all background processes, except those matching any of the
5659      * specified properties.
5660      *
5661      * @param minTargetSdk the target SDK version at or above which to preserve
5662      *                     processes, or {@code -1} to ignore the target SDK
5663      * @param maxProcState the process state at or below which to preserve
5664      *                     processes, or {@code -1} to ignore the process state
5665      */
killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState)5666     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5667         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5668                 != PackageManager.PERMISSION_GRANTED) {
5669             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5670                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5671                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5672             Slog.w(TAG, msg);
5673             throw new SecurityException(msg);
5674         }
5675 
5676         final long callingId = Binder.clearCallingIdentity();
5677         try {
5678             synchronized (this) {
5679                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5680                 final int NP = mProcessNames.getMap().size();
5681                 for (int ip = 0; ip < NP; ip++) {
5682                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5683                     final int NA = apps.size();
5684                     for (int ia = 0; ia < NA; ia++) {
5685                         final ProcessRecord app = apps.valueAt(ia);
5686                         if (app.removed) {
5687                             procs.add(app);
5688                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5689                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5690                             app.removed = true;
5691                             procs.add(app);
5692                         }
5693                     }
5694                 }
5695 
5696                 final int N = procs.size();
5697                 for (int i = 0; i < N; i++) {
5698                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5699                 }
5700             }
5701         } finally {
5702             Binder.restoreCallingIdentity(callingId);
5703         }
5704     }
5705 
5706     @Override
forceStopPackage(final String packageName, int userId)5707     public void forceStopPackage(final String packageName, int userId) {
5708         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5709                 != PackageManager.PERMISSION_GRANTED) {
5710             String msg = "Permission Denial: forceStopPackage() from pid="
5711                     + Binder.getCallingPid()
5712                     + ", uid=" + Binder.getCallingUid()
5713                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5714             Slog.w(TAG, msg);
5715             throw new SecurityException(msg);
5716         }
5717         final int callingPid = Binder.getCallingPid();
5718         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5719                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5720         long callingId = Binder.clearCallingIdentity();
5721         try {
5722             IPackageManager pm = AppGlobals.getPackageManager();
5723             synchronized(this) {
5724                 int[] users = userId == UserHandle.USER_ALL
5725                         ? mUserController.getUsers() : new int[] { userId };
5726                 for (int user : users) {
5727                     int pkgUid = -1;
5728                     try {
5729                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5730                                 user);
5731                     } catch (RemoteException e) {
5732                     }
5733                     if (pkgUid == -1) {
5734                         Slog.w(TAG, "Invalid packageName: " + packageName);
5735                         continue;
5736                     }
5737                     try {
5738                         pm.setPackageStoppedState(packageName, true, user);
5739                     } catch (RemoteException e) {
5740                     } catch (IllegalArgumentException e) {
5741                         Slog.w(TAG, "Failed trying to unstop package "
5742                                 + packageName + ": " + e);
5743                     }
5744                     if (mUserController.isUserRunningLocked(user, 0)) {
5745                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5746                         finishForceStopPackageLocked(packageName, pkgUid);
5747                     }
5748                 }
5749             }
5750         } finally {
5751             Binder.restoreCallingIdentity(callingId);
5752         }
5753     }
5754 
5755     @Override
addPackageDependency(String packageName)5756     public void addPackageDependency(String packageName) {
5757         synchronized (this) {
5758             int callingPid = Binder.getCallingPid();
5759             if (callingPid == Process.myPid()) {
5760                 //  Yeah, um, no.
5761                 return;
5762             }
5763             ProcessRecord proc;
5764             synchronized (mPidsSelfLocked) {
5765                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5766             }
5767             if (proc != null) {
5768                 if (proc.pkgDeps == null) {
5769                     proc.pkgDeps = new ArraySet<String>(1);
5770                 }
5771                 proc.pkgDeps.add(packageName);
5772             }
5773         }
5774     }
5775 
5776     /*
5777      * The pkg name and app id have to be specified.
5778      */
5779     @Override
killApplication(String pkg, int appId, int userId, String reason)5780     public void killApplication(String pkg, int appId, int userId, String reason) {
5781         if (pkg == null) {
5782             return;
5783         }
5784         // Make sure the uid is valid.
5785         if (appId < 0) {
5786             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5787             return;
5788         }
5789         int callerUid = Binder.getCallingUid();
5790         // Only the system server can kill an application
5791         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5792             // Post an aysnc message to kill the application
5793             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5794             msg.arg1 = appId;
5795             msg.arg2 = userId;
5796             Bundle bundle = new Bundle();
5797             bundle.putString("pkg", pkg);
5798             bundle.putString("reason", reason);
5799             msg.obj = bundle;
5800             mHandler.sendMessage(msg);
5801         } else {
5802             throw new SecurityException(callerUid + " cannot kill pkg: " +
5803                     pkg);
5804         }
5805     }
5806 
5807     @Override
closeSystemDialogs(String reason)5808     public void closeSystemDialogs(String reason) {
5809         enforceNotIsolatedCaller("closeSystemDialogs");
5810 
5811         final int pid = Binder.getCallingPid();
5812         final int uid = Binder.getCallingUid();
5813         final long origId = Binder.clearCallingIdentity();
5814         try {
5815             synchronized (this) {
5816                 // Only allow this from foreground processes, so that background
5817                 // applications can't abuse it to prevent system UI from being shown.
5818                 if (uid >= Process.FIRST_APPLICATION_UID) {
5819                     ProcessRecord proc;
5820                     synchronized (mPidsSelfLocked) {
5821                         proc = mPidsSelfLocked.get(pid);
5822                     }
5823                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5824                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5825                                 + " from background process " + proc);
5826                         return;
5827                     }
5828                 }
5829                 closeSystemDialogsLocked(reason);
5830             }
5831         } finally {
5832             Binder.restoreCallingIdentity(origId);
5833         }
5834     }
5835 
closeSystemDialogsLocked(String reason)5836     void closeSystemDialogsLocked(String reason) {
5837         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5838         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5839                 | Intent.FLAG_RECEIVER_FOREGROUND);
5840         if (reason != null) {
5841             intent.putExtra("reason", reason);
5842         }
5843         mWindowManager.closeSystemDialogs(reason);
5844 
5845         mStackSupervisor.closeSystemDialogsLocked();
5846 
5847         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5848                 AppOpsManager.OP_NONE, null, false, false,
5849                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5850     }
5851 
5852     @Override
getProcessMemoryInfo(int[] pids)5853     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5854         enforceNotIsolatedCaller("getProcessMemoryInfo");
5855         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5856         for (int i=pids.length-1; i>=0; i--) {
5857             ProcessRecord proc;
5858             int oomAdj;
5859             synchronized (this) {
5860                 synchronized (mPidsSelfLocked) {
5861                     proc = mPidsSelfLocked.get(pids[i]);
5862                     oomAdj = proc != null ? proc.setAdj : 0;
5863                 }
5864             }
5865             infos[i] = new Debug.MemoryInfo();
5866             Debug.getMemoryInfo(pids[i], infos[i]);
5867             if (proc != null) {
5868                 synchronized (this) {
5869                     if (proc.thread != null && proc.setAdj == oomAdj) {
5870                         // Record this for posterity if the process has been stable.
5871                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5872                                 infos[i].getTotalUss(), false, proc.pkgList);
5873                     }
5874                 }
5875             }
5876         }
5877         return infos;
5878     }
5879 
5880     @Override
getProcessPss(int[] pids)5881     public long[] getProcessPss(int[] pids) {
5882         enforceNotIsolatedCaller("getProcessPss");
5883         long[] pss = new long[pids.length];
5884         for (int i=pids.length-1; i>=0; i--) {
5885             ProcessRecord proc;
5886             int oomAdj;
5887             synchronized (this) {
5888                 synchronized (mPidsSelfLocked) {
5889                     proc = mPidsSelfLocked.get(pids[i]);
5890                     oomAdj = proc != null ? proc.setAdj : 0;
5891                 }
5892             }
5893             long[] tmpUss = new long[1];
5894             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5895             if (proc != null) {
5896                 synchronized (this) {
5897                     if (proc.thread != null && proc.setAdj == oomAdj) {
5898                         // Record this for posterity if the process has been stable.
5899                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5900                     }
5901                 }
5902             }
5903         }
5904         return pss;
5905     }
5906 
5907     @Override
killApplicationProcess(String processName, int uid)5908     public void killApplicationProcess(String processName, int uid) {
5909         if (processName == null) {
5910             return;
5911         }
5912 
5913         int callerUid = Binder.getCallingUid();
5914         // Only the system server can kill an application
5915         if (callerUid == Process.SYSTEM_UID) {
5916             synchronized (this) {
5917                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5918                 if (app != null && app.thread != null) {
5919                     try {
5920                         app.thread.scheduleSuicide();
5921                     } catch (RemoteException e) {
5922                         // If the other end already died, then our work here is done.
5923                     }
5924                 } else {
5925                     Slog.w(TAG, "Process/uid not found attempting kill of "
5926                             + processName + " / " + uid);
5927                 }
5928             }
5929         } else {
5930             throw new SecurityException(callerUid + " cannot kill app process: " +
5931                     processName);
5932         }
5933     }
5934 
forceStopPackageLocked(final String packageName, int uid, String reason)5935     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5936         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5937                 false, true, false, false, UserHandle.getUserId(uid), reason);
5938     }
5939 
finishForceStopPackageLocked(final String packageName, int uid)5940     private void finishForceStopPackageLocked(final String packageName, int uid) {
5941         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5942                 Uri.fromParts("package", packageName, null));
5943         if (!mProcessesReady) {
5944             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5945                     | Intent.FLAG_RECEIVER_FOREGROUND);
5946         }
5947         intent.putExtra(Intent.EXTRA_UID, uid);
5948         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5949         broadcastIntentLocked(null, null, intent,
5950                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5951                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5952     }
5953 
5954 
killPackageProcessesLocked(String packageName, int appId, int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart, boolean doit, boolean evenPersistent, String reason)5955     private final boolean killPackageProcessesLocked(String packageName, int appId,
5956             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5957             boolean doit, boolean evenPersistent, String reason) {
5958         ArrayList<ProcessRecord> procs = new ArrayList<>();
5959 
5960         // Remove all processes this package may have touched: all with the
5961         // same UID (except for the system or root user), and all whose name
5962         // matches the package name.
5963         final int NP = mProcessNames.getMap().size();
5964         for (int ip=0; ip<NP; ip++) {
5965             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5966             final int NA = apps.size();
5967             for (int ia=0; ia<NA; ia++) {
5968                 ProcessRecord app = apps.valueAt(ia);
5969                 if (app.persistent && !evenPersistent) {
5970                     // we don't kill persistent processes
5971                     continue;
5972                 }
5973                 if (app.removed) {
5974                     if (doit) {
5975                         procs.add(app);
5976                     }
5977                     continue;
5978                 }
5979 
5980                 // Skip process if it doesn't meet our oom adj requirement.
5981                 if (app.setAdj < minOomAdj) {
5982                     continue;
5983                 }
5984 
5985                 // If no package is specified, we call all processes under the
5986                 // give user id.
5987                 if (packageName == null) {
5988                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
5989                         continue;
5990                     }
5991                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
5992                         continue;
5993                     }
5994                 // Package has been specified, we want to hit all processes
5995                 // that match it.  We need to qualify this by the processes
5996                 // that are running under the specified app and user ID.
5997                 } else {
5998                     final boolean isDep = app.pkgDeps != null
5999                             && app.pkgDeps.contains(packageName);
6000                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6001                         continue;
6002                     }
6003                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6004                         continue;
6005                     }
6006                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6007                         continue;
6008                     }
6009                 }
6010 
6011                 // Process has passed all conditions, kill it!
6012                 if (!doit) {
6013                     return true;
6014                 }
6015                 app.removed = true;
6016                 procs.add(app);
6017             }
6018         }
6019 
6020         int N = procs.size();
6021         for (int i=0; i<N; i++) {
6022             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6023         }
6024         updateOomAdjLocked();
6025         return N > 0;
6026     }
6027 
cleanupDisabledPackageComponentsLocked( String packageName, int userId, boolean killProcess, String[] changedClasses)6028     private void cleanupDisabledPackageComponentsLocked(
6029             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6030 
6031         Set<String> disabledClasses = null;
6032         boolean packageDisabled = false;
6033         IPackageManager pm = AppGlobals.getPackageManager();
6034 
6035         if (changedClasses == null) {
6036             // Nothing changed...
6037             return;
6038         }
6039 
6040         // Determine enable/disable state of the package and its components.
6041         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6042         for (int i = changedClasses.length - 1; i >= 0; i--) {
6043             final String changedClass = changedClasses[i];
6044 
6045             if (changedClass.equals(packageName)) {
6046                 try {
6047                     // Entire package setting changed
6048                     enabled = pm.getApplicationEnabledSetting(packageName,
6049                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6050                 } catch (Exception e) {
6051                     // No such package/component; probably racing with uninstall.  In any
6052                     // event it means we have nothing further to do here.
6053                     return;
6054                 }
6055                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6056                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6057                 if (packageDisabled) {
6058                     // Entire package is disabled.
6059                     // No need to continue to check component states.
6060                     disabledClasses = null;
6061                     break;
6062                 }
6063             } else {
6064                 try {
6065                     enabled = pm.getComponentEnabledSetting(
6066                             new ComponentName(packageName, changedClass),
6067                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6068                 } catch (Exception e) {
6069                     // As above, probably racing with uninstall.
6070                     return;
6071                 }
6072                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6073                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6074                     if (disabledClasses == null) {
6075                         disabledClasses = new ArraySet<>(changedClasses.length);
6076                     }
6077                     disabledClasses.add(changedClass);
6078                 }
6079             }
6080         }
6081 
6082         if (!packageDisabled && disabledClasses == null) {
6083             // Nothing to do here...
6084             return;
6085         }
6086 
6087         // Clean-up disabled activities.
6088         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6089                 packageName, disabledClasses, true, false, userId) && mBooted) {
6090             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6091             mStackSupervisor.scheduleIdleLocked();
6092         }
6093 
6094         // Clean-up disabled tasks
6095         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6096 
6097         // Clean-up disabled services.
6098         mServices.bringDownDisabledPackageServicesLocked(
6099                 packageName, disabledClasses, userId, false, killProcess, true);
6100 
6101         // Clean-up disabled providers.
6102         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6103         mProviderMap.collectPackageProvidersLocked(
6104                 packageName, disabledClasses, true, false, userId, providers);
6105         for (int i = providers.size() - 1; i >= 0; i--) {
6106             removeDyingProviderLocked(null, providers.get(i), true);
6107         }
6108 
6109         // Clean-up disabled broadcast receivers.
6110         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6111             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6112                     packageName, disabledClasses, userId, true);
6113         }
6114 
6115     }
6116 
clearBroadcastQueueForUserLocked(int userId)6117     final boolean clearBroadcastQueueForUserLocked(int userId) {
6118         boolean didSomething = false;
6119         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6120             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6121                     null, null, userId, true);
6122         }
6123         return didSomething;
6124     }
6125 
forceStopPackageLocked(String packageName, int appId, boolean callerWillRestart, boolean purgeCache, boolean doit, boolean evenPersistent, boolean uninstalling, int userId, String reason)6126     final boolean forceStopPackageLocked(String packageName, int appId,
6127             boolean callerWillRestart, boolean purgeCache, boolean doit,
6128             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6129         int i;
6130 
6131         if (userId == UserHandle.USER_ALL && packageName == null) {
6132             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6133         }
6134 
6135         if (appId < 0 && packageName != null) {
6136             try {
6137                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6138                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6139             } catch (RemoteException e) {
6140             }
6141         }
6142 
6143         if (doit) {
6144             if (packageName != null) {
6145                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6146                         + " user=" + userId + ": " + reason);
6147             } else {
6148                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6149             }
6150 
6151             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6152         }
6153 
6154         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6155                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6156                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6157 
6158         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6159                 packageName, null, doit, evenPersistent, userId)) {
6160             if (!doit) {
6161                 return true;
6162             }
6163             didSomething = true;
6164         }
6165 
6166         if (mServices.bringDownDisabledPackageServicesLocked(
6167                 packageName, null, userId, evenPersistent, true, doit)) {
6168             if (!doit) {
6169                 return true;
6170             }
6171             didSomething = true;
6172         }
6173 
6174         if (packageName == null) {
6175             // Remove all sticky broadcasts from this user.
6176             mStickyBroadcasts.remove(userId);
6177         }
6178 
6179         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6180         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6181                 userId, providers)) {
6182             if (!doit) {
6183                 return true;
6184             }
6185             didSomething = true;
6186         }
6187         for (i = providers.size() - 1; i >= 0; i--) {
6188             removeDyingProviderLocked(null, providers.get(i), true);
6189         }
6190 
6191         // Remove transient permissions granted from/to this package/user
6192         removeUriPermissionsForPackageLocked(packageName, userId, false);
6193 
6194         if (doit) {
6195             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6196                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6197                         packageName, null, userId, doit);
6198             }
6199         }
6200 
6201         if (packageName == null || uninstalling) {
6202             // Remove pending intents.  For now we only do this when force
6203             // stopping users, because we have some problems when doing this
6204             // for packages -- app widgets are not currently cleaned up for
6205             // such packages, so they can be left with bad pending intents.
6206             if (mIntentSenderRecords.size() > 0) {
6207                 Iterator<WeakReference<PendingIntentRecord>> it
6208                         = mIntentSenderRecords.values().iterator();
6209                 while (it.hasNext()) {
6210                     WeakReference<PendingIntentRecord> wpir = it.next();
6211                     if (wpir == null) {
6212                         it.remove();
6213                         continue;
6214                     }
6215                     PendingIntentRecord pir = wpir.get();
6216                     if (pir == null) {
6217                         it.remove();
6218                         continue;
6219                     }
6220                     if (packageName == null) {
6221                         // Stopping user, remove all objects for the user.
6222                         if (pir.key.userId != userId) {
6223                             // Not the same user, skip it.
6224                             continue;
6225                         }
6226                     } else {
6227                         if (UserHandle.getAppId(pir.uid) != appId) {
6228                             // Different app id, skip it.
6229                             continue;
6230                         }
6231                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6232                             // Different user, skip it.
6233                             continue;
6234                         }
6235                         if (!pir.key.packageName.equals(packageName)) {
6236                             // Different package, skip it.
6237                             continue;
6238                         }
6239                     }
6240                     if (!doit) {
6241                         return true;
6242                     }
6243                     didSomething = true;
6244                     it.remove();
6245                     pir.canceled = true;
6246                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6247                         pir.key.activity.pendingResults.remove(pir.ref);
6248                     }
6249                 }
6250             }
6251         }
6252 
6253         if (doit) {
6254             if (purgeCache && packageName != null) {
6255                 AttributeCache ac = AttributeCache.instance();
6256                 if (ac != null) {
6257                     ac.removePackage(packageName);
6258                 }
6259             }
6260             if (mBooted) {
6261                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6262                 mStackSupervisor.scheduleIdleLocked();
6263             }
6264         }
6265 
6266         return didSomething;
6267     }
6268 
removeProcessNameLocked(final String name, final int uid)6269     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6270         ProcessRecord old = mProcessNames.remove(name, uid);
6271         if (old != null) {
6272             old.uidRecord.numProcs--;
6273             if (old.uidRecord.numProcs == 0) {
6274                 // No more processes using this uid, tell clients it is gone.
6275                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6276                         "No more processes in " + old.uidRecord);
6277                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6278                 mActiveUids.remove(uid);
6279                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6280             }
6281             old.uidRecord = null;
6282         }
6283         mIsolatedProcesses.remove(uid);
6284         return old;
6285     }
6286 
addProcessNameLocked(ProcessRecord proc)6287     private final void addProcessNameLocked(ProcessRecord proc) {
6288         // We shouldn't already have a process under this name, but just in case we
6289         // need to clean up whatever may be there now.
6290         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6291         if (old == proc && proc.persistent) {
6292             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6293             Slog.w(TAG, "Re-adding persistent process " + proc);
6294         } else if (old != null) {
6295             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6296         }
6297         UidRecord uidRec = mActiveUids.get(proc.uid);
6298         if (uidRec == null) {
6299             uidRec = new UidRecord(proc.uid);
6300             // This is the first appearance of the uid, report it now!
6301             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6302                     "Creating new process uid: " + uidRec);
6303             mActiveUids.put(proc.uid, uidRec);
6304             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6305             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6306         }
6307         proc.uidRecord = uidRec;
6308 
6309         // Reset render thread tid if it was already set, so new process can set it again.
6310         proc.renderThreadTid = 0;
6311         uidRec.numProcs++;
6312         mProcessNames.put(proc.processName, proc.uid, proc);
6313         if (proc.isolated) {
6314             mIsolatedProcesses.put(proc.uid, proc);
6315         }
6316     }
6317 
removeProcessLocked(ProcessRecord app, boolean callerWillRestart, boolean allowRestart, String reason)6318     boolean removeProcessLocked(ProcessRecord app,
6319             boolean callerWillRestart, boolean allowRestart, String reason) {
6320         final String name = app.processName;
6321         final int uid = app.uid;
6322         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6323             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6324 
6325         ProcessRecord old = mProcessNames.get(name, uid);
6326         if (old != app) {
6327             // This process is no longer active, so nothing to do.
6328             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6329             return false;
6330         }
6331         removeProcessNameLocked(name, uid);
6332         if (mHeavyWeightProcess == app) {
6333             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6334                     mHeavyWeightProcess.userId, 0));
6335             mHeavyWeightProcess = null;
6336         }
6337         boolean needRestart = false;
6338         if (app.pid > 0 && app.pid != MY_PID) {
6339             int pid = app.pid;
6340             synchronized (mPidsSelfLocked) {
6341                 mPidsSelfLocked.remove(pid);
6342                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6343             }
6344             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6345             if (app.isolated) {
6346                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6347             }
6348             boolean willRestart = false;
6349             if (app.persistent && !app.isolated) {
6350                 if (!callerWillRestart) {
6351                     willRestart = true;
6352                 } else {
6353                     needRestart = true;
6354                 }
6355             }
6356             app.kill(reason, true);
6357             handleAppDiedLocked(app, willRestart, allowRestart);
6358             if (willRestart) {
6359                 removeLruProcessLocked(app);
6360                 addAppLocked(app.info, false, null /* ABI override */);
6361             }
6362         } else {
6363             mRemovedProcesses.add(app);
6364         }
6365 
6366         return needRestart;
6367     }
6368 
processContentProviderPublishTimedOutLocked(ProcessRecord app)6369     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6370         cleanupAppInLaunchingProvidersLocked(app, true);
6371         removeProcessLocked(app, false, true, "timeout publishing content providers");
6372     }
6373 
processStartTimedOutLocked(ProcessRecord app)6374     private final void processStartTimedOutLocked(ProcessRecord app) {
6375         final int pid = app.pid;
6376         boolean gone = false;
6377         synchronized (mPidsSelfLocked) {
6378             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6379             if (knownApp != null && knownApp.thread == null) {
6380                 mPidsSelfLocked.remove(pid);
6381                 gone = true;
6382             }
6383         }
6384 
6385         if (gone) {
6386             Slog.w(TAG, "Process " + app + " failed to attach");
6387             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6388                     pid, app.uid, app.processName);
6389             removeProcessNameLocked(app.processName, app.uid);
6390             if (mHeavyWeightProcess == app) {
6391                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6392                         mHeavyWeightProcess.userId, 0));
6393                 mHeavyWeightProcess = null;
6394             }
6395             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6396             if (app.isolated) {
6397                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6398             }
6399             // Take care of any launching providers waiting for this process.
6400             cleanupAppInLaunchingProvidersLocked(app, true);
6401             // Take care of any services that are waiting for the process.
6402             mServices.processStartTimedOutLocked(app);
6403             app.kill("start timeout", true);
6404             removeLruProcessLocked(app);
6405             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6406                 Slog.w(TAG, "Unattached app died before backup, skipping");
6407                 try {
6408                     IBackupManager bm = IBackupManager.Stub.asInterface(
6409                             ServiceManager.getService(Context.BACKUP_SERVICE));
6410                     bm.agentDisconnected(app.info.packageName);
6411                 } catch (RemoteException e) {
6412                     // Can't happen; the backup manager is local
6413                 }
6414             }
6415             if (isPendingBroadcastProcessLocked(pid)) {
6416                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6417                 skipPendingBroadcastLocked(pid);
6418             }
6419         } else {
6420             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6421         }
6422     }
6423 
attachApplicationLocked(IApplicationThread thread, int pid)6424     private final boolean attachApplicationLocked(IApplicationThread thread,
6425             int pid) {
6426 
6427         // Find the application record that is being attached...  either via
6428         // the pid if we are running in multiple processes, or just pull the
6429         // next app record if we are emulating process with anonymous threads.
6430         ProcessRecord app;
6431         if (pid != MY_PID && pid >= 0) {
6432             synchronized (mPidsSelfLocked) {
6433                 app = mPidsSelfLocked.get(pid);
6434             }
6435         } else {
6436             app = null;
6437         }
6438 
6439         if (app == null) {
6440             Slog.w(TAG, "No pending application record for pid " + pid
6441                     + " (IApplicationThread " + thread + "); dropping process");
6442             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6443             if (pid > 0 && pid != MY_PID) {
6444                 Process.killProcessQuiet(pid);
6445                 //TODO: killProcessGroup(app.info.uid, pid);
6446             } else {
6447                 try {
6448                     thread.scheduleExit();
6449                 } catch (Exception e) {
6450                     // Ignore exceptions.
6451                 }
6452             }
6453             return false;
6454         }
6455 
6456         // If this application record is still attached to a previous
6457         // process, clean it up now.
6458         if (app.thread != null) {
6459             handleAppDiedLocked(app, true, true);
6460         }
6461 
6462         // Tell the process all about itself.
6463 
6464         if (DEBUG_ALL) Slog.v(
6465                 TAG, "Binding process pid " + pid + " to record " + app);
6466 
6467         final String processName = app.processName;
6468         try {
6469             AppDeathRecipient adr = new AppDeathRecipient(
6470                     app, pid, thread);
6471             thread.asBinder().linkToDeath(adr, 0);
6472             app.deathRecipient = adr;
6473         } catch (RemoteException e) {
6474             app.resetPackageList(mProcessStats);
6475             startProcessLocked(app, "link fail", processName);
6476             return false;
6477         }
6478 
6479         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6480 
6481         app.makeActive(thread, mProcessStats);
6482         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6483         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6484         app.forcingToForeground = null;
6485         updateProcessForegroundLocked(app, false, false);
6486         app.hasShownUi = false;
6487         app.debugging = false;
6488         app.cached = false;
6489         app.killedByAm = false;
6490 
6491         // We carefully use the same state that PackageManager uses for
6492         // filtering, since we use this flag to decide if we need to install
6493         // providers when user is unlocked later
6494         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6495 
6496         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6497 
6498         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6499         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6500 
6501         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6502             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6503             msg.obj = app;
6504             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6505         }
6506 
6507         if (!normalMode) {
6508             Slog.i(TAG, "Launching preboot mode app: " + app);
6509         }
6510 
6511         if (DEBUG_ALL) Slog.v(
6512             TAG, "New app record " + app
6513             + " thread=" + thread.asBinder() + " pid=" + pid);
6514         try {
6515             int testMode = IApplicationThread.DEBUG_OFF;
6516             if (mDebugApp != null && mDebugApp.equals(processName)) {
6517                 testMode = mWaitForDebugger
6518                     ? IApplicationThread.DEBUG_WAIT
6519                     : IApplicationThread.DEBUG_ON;
6520                 app.debugging = true;
6521                 if (mDebugTransient) {
6522                     mDebugApp = mOrigDebugApp;
6523                     mWaitForDebugger = mOrigWaitForDebugger;
6524                 }
6525             }
6526             String profileFile = app.instrumentationProfileFile;
6527             ParcelFileDescriptor profileFd = null;
6528             int samplingInterval = 0;
6529             boolean profileAutoStop = false;
6530             if (mProfileApp != null && mProfileApp.equals(processName)) {
6531                 mProfileProc = app;
6532                 profileFile = mProfileFile;
6533                 profileFd = mProfileFd;
6534                 samplingInterval = mSamplingInterval;
6535                 profileAutoStop = mAutoStopProfiler;
6536             }
6537             boolean enableTrackAllocation = false;
6538             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6539                 enableTrackAllocation = true;
6540                 mTrackAllocationApp = null;
6541             }
6542 
6543             // If the app is being launched for restore or full backup, set it up specially
6544             boolean isRestrictedBackupMode = false;
6545             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6546                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6547                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6548                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6549                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6550             }
6551 
6552             if (app.instrumentationClass != null) {
6553                 notifyPackageUse(app.instrumentationClass.getPackageName(),
6554                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6555             }
6556             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6557                     + processName + " with config " + mConfiguration);
6558             ApplicationInfo appInfo = app.instrumentationInfo != null
6559                     ? app.instrumentationInfo : app.info;
6560             app.compat = compatibilityInfoForPackageLocked(appInfo);
6561             if (profileFd != null) {
6562                 profileFd = profileFd.dup();
6563             }
6564             ProfilerInfo profilerInfo = profileFile == null ? null
6565                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6566             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6567                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6568                     app.instrumentationUiAutomationConnection, testMode,
6569                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6570                     isRestrictedBackupMode || !normalMode, app.persistent,
6571                     new Configuration(mConfiguration), app.compat,
6572                     getCommonServicesLocked(app.isolated),
6573                     mCoreSettingsObserver.getCoreSettingsLocked());
6574             updateLruProcessLocked(app, false, null);
6575             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6576         } catch (Exception e) {
6577             // todo: Yikes!  What should we do?  For now we will try to
6578             // start another process, but that could easily get us in
6579             // an infinite loop of restarting processes...
6580             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6581 
6582             app.resetPackageList(mProcessStats);
6583             app.unlinkDeathRecipient();
6584             startProcessLocked(app, "bind fail", processName);
6585             return false;
6586         }
6587 
6588         // Remove this record from the list of starting applications.
6589         mPersistentStartingProcesses.remove(app);
6590         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6591                 "Attach application locked removing on hold: " + app);
6592         mProcessesOnHold.remove(app);
6593 
6594         boolean badApp = false;
6595         boolean didSomething = false;
6596 
6597         // See if the top visible activity is waiting to run in this process...
6598         if (normalMode) {
6599             try {
6600                 if (mStackSupervisor.attachApplicationLocked(app)) {
6601                     didSomething = true;
6602                 }
6603             } catch (Exception e) {
6604                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6605                 badApp = true;
6606             }
6607         }
6608 
6609         // Find any services that should be running in this process...
6610         if (!badApp) {
6611             try {
6612                 didSomething |= mServices.attachApplicationLocked(app, processName);
6613             } catch (Exception e) {
6614                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6615                 badApp = true;
6616             }
6617         }
6618 
6619         // Check if a next-broadcast receiver is in this process...
6620         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6621             try {
6622                 didSomething |= sendPendingBroadcastsLocked(app);
6623             } catch (Exception e) {
6624                 // If the app died trying to launch the receiver we declare it 'bad'
6625                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6626                 badApp = true;
6627             }
6628         }
6629 
6630         // Check whether the next backup agent is in this process...
6631         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6632             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6633                     "New app is backup target, launching agent for " + app);
6634             notifyPackageUse(mBackupTarget.appInfo.packageName,
6635                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6636             try {
6637                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6638                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6639                         mBackupTarget.backupMode);
6640             } catch (Exception e) {
6641                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6642                 badApp = true;
6643             }
6644         }
6645 
6646         if (badApp) {
6647             app.kill("error during init", true);
6648             handleAppDiedLocked(app, false, true);
6649             return false;
6650         }
6651 
6652         if (!didSomething) {
6653             updateOomAdjLocked();
6654         }
6655 
6656         return true;
6657     }
6658 
6659     @Override
attachApplication(IApplicationThread thread)6660     public final void attachApplication(IApplicationThread thread) {
6661         synchronized (this) {
6662             int callingPid = Binder.getCallingPid();
6663             final long origId = Binder.clearCallingIdentity();
6664             attachApplicationLocked(thread, callingPid);
6665             Binder.restoreCallingIdentity(origId);
6666         }
6667     }
6668 
6669     @Override
activityIdle(IBinder token, Configuration config, boolean stopProfiling)6670     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6671         final long origId = Binder.clearCallingIdentity();
6672         synchronized (this) {
6673             ActivityStack stack = ActivityRecord.getStackLocked(token);
6674             if (stack != null) {
6675                 ActivityRecord r =
6676                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6677                 if (stopProfiling) {
6678                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6679                         try {
6680                             mProfileFd.close();
6681                         } catch (IOException e) {
6682                         }
6683                         clearProfilerLocked();
6684                     }
6685                 }
6686             }
6687         }
6688         Binder.restoreCallingIdentity(origId);
6689     }
6690 
postFinishBooting(boolean finishBooting, boolean enableScreen)6691     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6692         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6693                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6694     }
6695 
enableScreenAfterBoot()6696     void enableScreenAfterBoot() {
6697         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6698                 SystemClock.uptimeMillis());
6699         mWindowManager.enableScreenAfterBoot();
6700 
6701         synchronized (this) {
6702             updateEventDispatchingLocked();
6703         }
6704     }
6705 
6706     @Override
showBootMessage(final CharSequence msg, final boolean always)6707     public void showBootMessage(final CharSequence msg, final boolean always) {
6708         if (Binder.getCallingUid() != Process.myUid()) {
6709             throw new SecurityException();
6710         }
6711         mWindowManager.showBootMessage(msg, always);
6712     }
6713 
6714     @Override
keyguardWaitingForActivityDrawn()6715     public void keyguardWaitingForActivityDrawn() {
6716         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6717         final long token = Binder.clearCallingIdentity();
6718         try {
6719             synchronized (this) {
6720                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6721                 mWindowManager.keyguardWaitingForActivityDrawn();
6722                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6723                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6724                     updateSleepIfNeededLocked();
6725                 }
6726             }
6727         } finally {
6728             Binder.restoreCallingIdentity(token);
6729         }
6730     }
6731 
6732     @Override
keyguardGoingAway(int flags)6733     public void keyguardGoingAway(int flags) {
6734         enforceNotIsolatedCaller("keyguardGoingAway");
6735         final long token = Binder.clearCallingIdentity();
6736         try {
6737             synchronized (this) {
6738                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6739                 mWindowManager.keyguardGoingAway(flags);
6740                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6741                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6742                     updateSleepIfNeededLocked();
6743 
6744                     // Some stack visibility might change (e.g. docked stack)
6745                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6746                     applyVrModeIfNeededLocked(mFocusedActivity, true);
6747                 }
6748             }
6749         } finally {
6750             Binder.restoreCallingIdentity(token);
6751         }
6752     }
6753 
finishBooting()6754     final void finishBooting() {
6755         synchronized (this) {
6756             if (!mBootAnimationComplete) {
6757                 mCallFinishBooting = true;
6758                 return;
6759             }
6760             mCallFinishBooting = false;
6761         }
6762 
6763         ArraySet<String> completedIsas = new ArraySet<String>();
6764         for (String abi : Build.SUPPORTED_ABIS) {
6765             Process.establishZygoteConnectionForAbi(abi);
6766             final String instructionSet = VMRuntime.getInstructionSet(abi);
6767             if (!completedIsas.contains(instructionSet)) {
6768                 try {
6769                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6770                 } catch (InstallerException e) {
6771                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6772                             e.getMessage() +")");
6773                 }
6774                 completedIsas.add(instructionSet);
6775             }
6776         }
6777 
6778         IntentFilter pkgFilter = new IntentFilter();
6779         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6780         pkgFilter.addDataScheme("package");
6781         mContext.registerReceiver(new BroadcastReceiver() {
6782             @Override
6783             public void onReceive(Context context, Intent intent) {
6784                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6785                 if (pkgs != null) {
6786                     for (String pkg : pkgs) {
6787                         synchronized (ActivityManagerService.this) {
6788                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6789                                     0, "query restart")) {
6790                                 setResultCode(Activity.RESULT_OK);
6791                                 return;
6792                             }
6793                         }
6794                     }
6795                 }
6796             }
6797         }, pkgFilter);
6798 
6799         IntentFilter dumpheapFilter = new IntentFilter();
6800         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6801         mContext.registerReceiver(new BroadcastReceiver() {
6802             @Override
6803             public void onReceive(Context context, Intent intent) {
6804                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6805                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6806                 } else {
6807                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6808                 }
6809             }
6810         }, dumpheapFilter);
6811 
6812         // Let system services know.
6813         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6814 
6815         synchronized (this) {
6816             // Ensure that any processes we had put on hold are now started
6817             // up.
6818             final int NP = mProcessesOnHold.size();
6819             if (NP > 0) {
6820                 ArrayList<ProcessRecord> procs =
6821                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6822                 for (int ip=0; ip<NP; ip++) {
6823                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6824                             + procs.get(ip));
6825                     startProcessLocked(procs.get(ip), "on-hold", null);
6826                 }
6827             }
6828 
6829             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6830                 // Start looking for apps that are abusing wake locks.
6831                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6832                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6833                 // Tell anyone interested that we are done booting!
6834                 SystemProperties.set("sys.boot_completed", "1");
6835 
6836                 // And trigger dev.bootcomplete if we are not showing encryption progress
6837                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6838                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6839                     SystemProperties.set("dev.bootcomplete", "1");
6840                 }
6841                 mUserController.sendBootCompletedLocked(
6842                         new IIntentReceiver.Stub() {
6843                             @Override
6844                             public void performReceive(Intent intent, int resultCode,
6845                                     String data, Bundle extras, boolean ordered,
6846                                     boolean sticky, int sendingUser) {
6847                                 synchronized (ActivityManagerService.this) {
6848                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6849                                             true, false);
6850                                 }
6851                             }
6852                         });
6853                 scheduleStartProfilesLocked();
6854             }
6855         }
6856     }
6857 
6858     @Override
bootAnimationComplete()6859     public void bootAnimationComplete() {
6860         final boolean callFinishBooting;
6861         synchronized (this) {
6862             callFinishBooting = mCallFinishBooting;
6863             mBootAnimationComplete = true;
6864         }
6865         if (callFinishBooting) {
6866             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6867             finishBooting();
6868             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6869         }
6870     }
6871 
ensureBootCompleted()6872     final void ensureBootCompleted() {
6873         boolean booting;
6874         boolean enableScreen;
6875         synchronized (this) {
6876             booting = mBooting;
6877             mBooting = false;
6878             enableScreen = !mBooted;
6879             mBooted = true;
6880         }
6881 
6882         if (booting) {
6883             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6884             finishBooting();
6885             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6886         }
6887 
6888         if (enableScreen) {
6889             enableScreenAfterBoot();
6890         }
6891     }
6892 
6893     @Override
activityResumed(IBinder token)6894     public final void activityResumed(IBinder token) {
6895         final long origId = Binder.clearCallingIdentity();
6896         synchronized(this) {
6897             ActivityStack stack = ActivityRecord.getStackLocked(token);
6898             if (stack != null) {
6899                 stack.activityResumedLocked(token);
6900             }
6901         }
6902         Binder.restoreCallingIdentity(origId);
6903     }
6904 
6905     @Override
activityPaused(IBinder token)6906     public final void activityPaused(IBinder token) {
6907         final long origId = Binder.clearCallingIdentity();
6908         synchronized(this) {
6909             ActivityStack stack = ActivityRecord.getStackLocked(token);
6910             if (stack != null) {
6911                 stack.activityPausedLocked(token, false);
6912             }
6913         }
6914         Binder.restoreCallingIdentity(origId);
6915     }
6916 
6917     @Override
activityStopped(IBinder token, Bundle icicle, PersistableBundle persistentState, CharSequence description)6918     public final void activityStopped(IBinder token, Bundle icicle,
6919             PersistableBundle persistentState, CharSequence description) {
6920         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6921 
6922         // Refuse possible leaked file descriptors
6923         if (icicle != null && icicle.hasFileDescriptors()) {
6924             throw new IllegalArgumentException("File descriptors passed in Bundle");
6925         }
6926 
6927         final long origId = Binder.clearCallingIdentity();
6928 
6929         synchronized (this) {
6930             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6931             if (r != null) {
6932                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6933             }
6934         }
6935 
6936         trimApplications();
6937 
6938         Binder.restoreCallingIdentity(origId);
6939     }
6940 
6941     @Override
activityDestroyed(IBinder token)6942     public final void activityDestroyed(IBinder token) {
6943         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6944         synchronized (this) {
6945             ActivityStack stack = ActivityRecord.getStackLocked(token);
6946             if (stack != null) {
6947                 stack.activityDestroyedLocked(token, "activityDestroyed");
6948             }
6949         }
6950     }
6951 
6952     @Override
activityRelaunched(IBinder token)6953     public final void activityRelaunched(IBinder token) {
6954         final long origId = Binder.clearCallingIdentity();
6955         synchronized (this) {
6956             mStackSupervisor.activityRelaunchedLocked(token);
6957         }
6958         Binder.restoreCallingIdentity(origId);
6959     }
6960 
6961     @Override
reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration, int[] verticalSizeConfigurations, int[] smallestSizeConfigurations)6962     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6963             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6964         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6965                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6966         synchronized (this) {
6967             ActivityRecord record = ActivityRecord.isInStackLocked(token);
6968             if (record == null) {
6969                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6970                         + "found for: " + token);
6971             }
6972             record.setSizeConfigurations(horizontalSizeConfiguration,
6973                     verticalSizeConfigurations, smallestSizeConfigurations);
6974         }
6975     }
6976 
6977     @Override
backgroundResourcesReleased(IBinder token)6978     public final void backgroundResourcesReleased(IBinder token) {
6979         final long origId = Binder.clearCallingIdentity();
6980         try {
6981             synchronized (this) {
6982                 ActivityStack stack = ActivityRecord.getStackLocked(token);
6983                 if (stack != null) {
6984                     stack.backgroundResourcesReleased();
6985                 }
6986             }
6987         } finally {
6988             Binder.restoreCallingIdentity(origId);
6989         }
6990     }
6991 
6992     @Override
notifyLaunchTaskBehindComplete(IBinder token)6993     public final void notifyLaunchTaskBehindComplete(IBinder token) {
6994         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
6995     }
6996 
6997     @Override
notifyEnterAnimationComplete(IBinder token)6998     public final void notifyEnterAnimationComplete(IBinder token) {
6999         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7000     }
7001 
7002     @Override
getCallingPackage(IBinder token)7003     public String getCallingPackage(IBinder token) {
7004         synchronized (this) {
7005             ActivityRecord r = getCallingRecordLocked(token);
7006             return r != null ? r.info.packageName : null;
7007         }
7008     }
7009 
7010     @Override
getCallingActivity(IBinder token)7011     public ComponentName getCallingActivity(IBinder token) {
7012         synchronized (this) {
7013             ActivityRecord r = getCallingRecordLocked(token);
7014             return r != null ? r.intent.getComponent() : null;
7015         }
7016     }
7017 
getCallingRecordLocked(IBinder token)7018     private ActivityRecord getCallingRecordLocked(IBinder token) {
7019         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7020         if (r == null) {
7021             return null;
7022         }
7023         return r.resultTo;
7024     }
7025 
7026     @Override
getActivityClassForToken(IBinder token)7027     public ComponentName getActivityClassForToken(IBinder token) {
7028         synchronized(this) {
7029             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7030             if (r == null) {
7031                 return null;
7032             }
7033             return r.intent.getComponent();
7034         }
7035     }
7036 
7037     @Override
getPackageForToken(IBinder token)7038     public String getPackageForToken(IBinder token) {
7039         synchronized(this) {
7040             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7041             if (r == null) {
7042                 return null;
7043             }
7044             return r.packageName;
7045         }
7046     }
7047 
7048     @Override
isRootVoiceInteraction(IBinder token)7049     public boolean isRootVoiceInteraction(IBinder token) {
7050         synchronized(this) {
7051             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7052             if (r == null) {
7053                 return false;
7054             }
7055             return r.rootVoiceInteraction;
7056         }
7057     }
7058 
7059     @Override
getIntentSender(int type, String packageName, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle bOptions, int userId)7060     public IIntentSender getIntentSender(int type,
7061             String packageName, IBinder token, String resultWho,
7062             int requestCode, Intent[] intents, String[] resolvedTypes,
7063             int flags, Bundle bOptions, int userId) {
7064         enforceNotIsolatedCaller("getIntentSender");
7065         // Refuse possible leaked file descriptors
7066         if (intents != null) {
7067             if (intents.length < 1) {
7068                 throw new IllegalArgumentException("Intents array length must be >= 1");
7069             }
7070             for (int i=0; i<intents.length; i++) {
7071                 Intent intent = intents[i];
7072                 if (intent != null) {
7073                     if (intent.hasFileDescriptors()) {
7074                         throw new IllegalArgumentException("File descriptors passed in Intent");
7075                     }
7076                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7077                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7078                         throw new IllegalArgumentException(
7079                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7080                     }
7081                     intents[i] = new Intent(intent);
7082                 }
7083             }
7084             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7085                 throw new IllegalArgumentException(
7086                         "Intent array length does not match resolvedTypes length");
7087             }
7088         }
7089         if (bOptions != null) {
7090             if (bOptions.hasFileDescriptors()) {
7091                 throw new IllegalArgumentException("File descriptors passed in options");
7092             }
7093         }
7094 
7095         synchronized(this) {
7096             int callingUid = Binder.getCallingUid();
7097             int origUserId = userId;
7098             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7099                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7100                     ALLOW_NON_FULL, "getIntentSender", null);
7101             if (origUserId == UserHandle.USER_CURRENT) {
7102                 // We don't want to evaluate this until the pending intent is
7103                 // actually executed.  However, we do want to always do the
7104                 // security checking for it above.
7105                 userId = UserHandle.USER_CURRENT;
7106             }
7107             try {
7108                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7109                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7110                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7111                     if (!UserHandle.isSameApp(callingUid, uid)) {
7112                         String msg = "Permission Denial: getIntentSender() from pid="
7113                             + Binder.getCallingPid()
7114                             + ", uid=" + Binder.getCallingUid()
7115                             + ", (need uid=" + uid + ")"
7116                             + " is not allowed to send as package " + packageName;
7117                         Slog.w(TAG, msg);
7118                         throw new SecurityException(msg);
7119                     }
7120                 }
7121 
7122                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7123                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7124 
7125             } catch (RemoteException e) {
7126                 throw new SecurityException(e);
7127             }
7128         }
7129     }
7130 
getIntentSenderLocked(int type, String packageName, int callingUid, int userId, IBinder token, String resultWho, int requestCode, Intent[] intents, String[] resolvedTypes, int flags, Bundle bOptions)7131     IIntentSender getIntentSenderLocked(int type, String packageName,
7132             int callingUid, int userId, IBinder token, String resultWho,
7133             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7134             Bundle bOptions) {
7135         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7136         ActivityRecord activity = null;
7137         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7138             activity = ActivityRecord.isInStackLocked(token);
7139             if (activity == null) {
7140                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7141                 return null;
7142             }
7143             if (activity.finishing) {
7144                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7145                 return null;
7146             }
7147         }
7148 
7149         // We're going to be splicing together extras before sending, so we're
7150         // okay poking into any contained extras.
7151         if (intents != null) {
7152             for (int i = 0; i < intents.length; i++) {
7153                 intents[i].setDefusable(true);
7154             }
7155         }
7156         Bundle.setDefusable(bOptions, true);
7157 
7158         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7159         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7160         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7161         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7162                 |PendingIntent.FLAG_UPDATE_CURRENT);
7163 
7164         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7165                 type, packageName, activity, resultWho,
7166                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7167         WeakReference<PendingIntentRecord> ref;
7168         ref = mIntentSenderRecords.get(key);
7169         PendingIntentRecord rec = ref != null ? ref.get() : null;
7170         if (rec != null) {
7171             if (!cancelCurrent) {
7172                 if (updateCurrent) {
7173                     if (rec.key.requestIntent != null) {
7174                         rec.key.requestIntent.replaceExtras(intents != null ?
7175                                 intents[intents.length - 1] : null);
7176                     }
7177                     if (intents != null) {
7178                         intents[intents.length-1] = rec.key.requestIntent;
7179                         rec.key.allIntents = intents;
7180                         rec.key.allResolvedTypes = resolvedTypes;
7181                     } else {
7182                         rec.key.allIntents = null;
7183                         rec.key.allResolvedTypes = null;
7184                     }
7185                 }
7186                 return rec;
7187             }
7188             rec.canceled = true;
7189             mIntentSenderRecords.remove(key);
7190         }
7191         if (noCreate) {
7192             return rec;
7193         }
7194         rec = new PendingIntentRecord(this, key, callingUid);
7195         mIntentSenderRecords.put(key, rec.ref);
7196         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7197             if (activity.pendingResults == null) {
7198                 activity.pendingResults
7199                         = new HashSet<WeakReference<PendingIntentRecord>>();
7200             }
7201             activity.pendingResults.add(rec.ref);
7202         }
7203         return rec;
7204     }
7205 
7206     @Override
sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType, IIntentReceiver finishedReceiver, String requiredPermission, Bundle options)7207     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7208             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7209         if (target instanceof PendingIntentRecord) {
7210             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7211                     finishedReceiver, requiredPermission, options);
7212         } else {
7213             if (intent == null) {
7214                 // Weird case: someone has given us their own custom IIntentSender, and now
7215                 // they have someone else trying to send to it but of course this isn't
7216                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7217                 // supplying an Intent... but we never want to dispatch a null Intent to
7218                 // a receiver, so um...  let's make something up.
7219                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7220                 intent = new Intent(Intent.ACTION_MAIN);
7221             }
7222             try {
7223                 target.send(code, intent, resolvedType, null, requiredPermission, options);
7224             } catch (RemoteException e) {
7225             }
7226             // Platform code can rely on getting a result back when the send is done, but if
7227             // this intent sender is from outside of the system we can't rely on it doing that.
7228             // So instead we don't give it the result receiver, and instead just directly
7229             // report the finish immediately.
7230             if (finishedReceiver != null) {
7231                 try {
7232                     finishedReceiver.performReceive(intent, 0,
7233                             null, null, false, false, UserHandle.getCallingUserId());
7234                 } catch (RemoteException e) {
7235                 }
7236             }
7237             return 0;
7238         }
7239     }
7240 
7241     /**
7242      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7243      *
7244      * <p>{@code callerUid} must be allowed to request such whitelist by calling
7245      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7246      */
tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration)7247     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7248         if (DEBUG_WHITELISTS) {
7249             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7250                     + targetUid + ", " + duration + ")");
7251         }
7252         synchronized (mPidsSelfLocked) {
7253             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7254             if (pr == null) {
7255                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7256                 return;
7257             }
7258             if (!pr.whitelistManager) {
7259                 if (DEBUG_WHITELISTS) {
7260                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7261                             + callerPid + " is not allowed");
7262                 }
7263                 return;
7264             }
7265         }
7266 
7267         final long token = Binder.clearCallingIdentity();
7268         try {
7269             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7270                     true, "pe from uid:" + callerUid);
7271         } finally {
7272             Binder.restoreCallingIdentity(token);
7273         }
7274     }
7275 
7276     @Override
cancelIntentSender(IIntentSender sender)7277     public void cancelIntentSender(IIntentSender sender) {
7278         if (!(sender instanceof PendingIntentRecord)) {
7279             return;
7280         }
7281         synchronized(this) {
7282             PendingIntentRecord rec = (PendingIntentRecord)sender;
7283             try {
7284                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7285                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7286                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7287                     String msg = "Permission Denial: cancelIntentSender() from pid="
7288                         + Binder.getCallingPid()
7289                         + ", uid=" + Binder.getCallingUid()
7290                         + " is not allowed to cancel packges "
7291                         + rec.key.packageName;
7292                     Slog.w(TAG, msg);
7293                     throw new SecurityException(msg);
7294                 }
7295             } catch (RemoteException e) {
7296                 throw new SecurityException(e);
7297             }
7298             cancelIntentSenderLocked(rec, true);
7299         }
7300     }
7301 
cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity)7302     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7303         rec.canceled = true;
7304         mIntentSenderRecords.remove(rec.key);
7305         if (cleanActivity && rec.key.activity != null) {
7306             rec.key.activity.pendingResults.remove(rec.ref);
7307         }
7308     }
7309 
7310     @Override
getPackageForIntentSender(IIntentSender pendingResult)7311     public String getPackageForIntentSender(IIntentSender pendingResult) {
7312         if (!(pendingResult instanceof PendingIntentRecord)) {
7313             return null;
7314         }
7315         try {
7316             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7317             return res.key.packageName;
7318         } catch (ClassCastException e) {
7319         }
7320         return null;
7321     }
7322 
7323     @Override
getUidForIntentSender(IIntentSender sender)7324     public int getUidForIntentSender(IIntentSender sender) {
7325         if (sender instanceof PendingIntentRecord) {
7326             try {
7327                 PendingIntentRecord res = (PendingIntentRecord)sender;
7328                 return res.uid;
7329             } catch (ClassCastException e) {
7330             }
7331         }
7332         return -1;
7333     }
7334 
7335     @Override
isIntentSenderTargetedToPackage(IIntentSender pendingResult)7336     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7337         if (!(pendingResult instanceof PendingIntentRecord)) {
7338             return false;
7339         }
7340         try {
7341             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7342             if (res.key.allIntents == null) {
7343                 return false;
7344             }
7345             for (int i=0; i<res.key.allIntents.length; i++) {
7346                 Intent intent = res.key.allIntents[i];
7347                 if (intent.getPackage() != null && intent.getComponent() != null) {
7348                     return false;
7349                 }
7350             }
7351             return true;
7352         } catch (ClassCastException e) {
7353         }
7354         return false;
7355     }
7356 
7357     @Override
isIntentSenderAnActivity(IIntentSender pendingResult)7358     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7359         if (!(pendingResult instanceof PendingIntentRecord)) {
7360             return false;
7361         }
7362         try {
7363             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7364             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7365                 return true;
7366             }
7367             return false;
7368         } catch (ClassCastException e) {
7369         }
7370         return false;
7371     }
7372 
7373     @Override
getIntentForIntentSender(IIntentSender pendingResult)7374     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7375         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7376                 "getIntentForIntentSender()");
7377         if (!(pendingResult instanceof PendingIntentRecord)) {
7378             return null;
7379         }
7380         try {
7381             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7382             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7383         } catch (ClassCastException e) {
7384         }
7385         return null;
7386     }
7387 
7388     @Override
getTagForIntentSender(IIntentSender pendingResult, String prefix)7389     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7390         if (!(pendingResult instanceof PendingIntentRecord)) {
7391             return null;
7392         }
7393         try {
7394             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7395             synchronized (this) {
7396                 return getTagForIntentSenderLocked(res, prefix);
7397             }
7398         } catch (ClassCastException e) {
7399         }
7400         return null;
7401     }
7402 
getTagForIntentSenderLocked(PendingIntentRecord res, String prefix)7403     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7404         final Intent intent = res.key.requestIntent;
7405         if (intent != null) {
7406             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7407                     || res.lastTagPrefix.equals(prefix))) {
7408                 return res.lastTag;
7409             }
7410             res.lastTagPrefix = prefix;
7411             final StringBuilder sb = new StringBuilder(128);
7412             if (prefix != null) {
7413                 sb.append(prefix);
7414             }
7415             if (intent.getAction() != null) {
7416                 sb.append(intent.getAction());
7417             } else if (intent.getComponent() != null) {
7418                 intent.getComponent().appendShortString(sb);
7419             } else {
7420                 sb.append("?");
7421             }
7422             return res.lastTag = sb.toString();
7423         }
7424         return null;
7425     }
7426 
7427     @Override
setProcessLimit(int max)7428     public void setProcessLimit(int max) {
7429         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7430                 "setProcessLimit()");
7431         synchronized (this) {
7432             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7433             mProcessLimitOverride = max;
7434         }
7435         trimApplications();
7436     }
7437 
7438     @Override
7439     public int getProcessLimit() {
7440         synchronized (this) {
7441             return mProcessLimitOverride;
7442         }
7443     }
7444 
7445     void foregroundTokenDied(ForegroundToken token) {
7446         synchronized (ActivityManagerService.this) {
7447             synchronized (mPidsSelfLocked) {
7448                 ForegroundToken cur
7449                     = mForegroundProcesses.get(token.pid);
7450                 if (cur != token) {
7451                     return;
7452                 }
7453                 mForegroundProcesses.remove(token.pid);
7454                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7455                 if (pr == null) {
7456                     return;
7457                 }
7458                 pr.forcingToForeground = null;
7459                 updateProcessForegroundLocked(pr, false, false);
7460             }
7461             updateOomAdjLocked();
7462         }
7463     }
7464 
7465     @Override
7466     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7467         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7468                 "setProcessForeground()");
7469         synchronized(this) {
7470             boolean changed = false;
7471 
7472             synchronized (mPidsSelfLocked) {
7473                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7474                 if (pr == null && isForeground) {
7475                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7476                     return;
7477                 }
7478                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7479                 if (oldToken != null) {
7480                     oldToken.token.unlinkToDeath(oldToken, 0);
7481                     mForegroundProcesses.remove(pid);
7482                     if (pr != null) {
7483                         pr.forcingToForeground = null;
7484                     }
7485                     changed = true;
7486                 }
7487                 if (isForeground && token != null) {
7488                     ForegroundToken newToken = new ForegroundToken() {
7489                         @Override
7490                         public void binderDied() {
7491                             foregroundTokenDied(this);
7492                         }
7493                     };
7494                     newToken.pid = pid;
7495                     newToken.token = token;
7496                     try {
7497                         token.linkToDeath(newToken, 0);
7498                         mForegroundProcesses.put(pid, newToken);
7499                         pr.forcingToForeground = token;
7500                         changed = true;
7501                     } catch (RemoteException e) {
7502                         // If the process died while doing this, we will later
7503                         // do the cleanup with the process death link.
7504                     }
7505                 }
7506             }
7507 
7508             if (changed) {
7509                 updateOomAdjLocked();
7510             }
7511         }
7512     }
7513 
7514     @Override
7515     public boolean isAppForeground(int uid) throws RemoteException {
7516         synchronized (this) {
7517             UidRecord uidRec = mActiveUids.get(uid);
7518             if (uidRec == null || uidRec.idle) {
7519                 return false;
7520             }
7521             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7522         }
7523     }
7524 
7525     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7526     // be guarded by permission checking.
7527     int getUidState(int uid) {
7528         synchronized (this) {
7529             UidRecord uidRec = mActiveUids.get(uid);
7530             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7531         }
7532     }
7533 
7534     @Override
7535     public boolean isInMultiWindowMode(IBinder token) {
7536         final long origId = Binder.clearCallingIdentity();
7537         try {
7538             synchronized(this) {
7539                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7540                 if (r == null) {
7541                     return false;
7542                 }
7543                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7544                 return !r.task.mFullscreen;
7545             }
7546         } finally {
7547             Binder.restoreCallingIdentity(origId);
7548         }
7549     }
7550 
7551     @Override
7552     public boolean isInPictureInPictureMode(IBinder token) {
7553         final long origId = Binder.clearCallingIdentity();
7554         try {
7555             synchronized(this) {
7556                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7557                 if (stack == null) {
7558                     return false;
7559                 }
7560                 return stack.mStackId == PINNED_STACK_ID;
7561             }
7562         } finally {
7563             Binder.restoreCallingIdentity(origId);
7564         }
7565     }
7566 
7567     @Override
7568     public void enterPictureInPictureMode(IBinder token) {
7569         final long origId = Binder.clearCallingIdentity();
7570         try {
7571             synchronized(this) {
7572                 if (!mSupportsPictureInPicture) {
7573                     throw new IllegalStateException("enterPictureInPictureMode: "
7574                             + "Device doesn't support picture-in-picture mode.");
7575                 }
7576 
7577                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7578 
7579                 if (r == null) {
7580                     throw new IllegalStateException("enterPictureInPictureMode: "
7581                             + "Can't find activity for token=" + token);
7582                 }
7583 
7584                 if (!r.supportsPictureInPicture()) {
7585                     throw new IllegalArgumentException("enterPictureInPictureMode: "
7586                             + "Picture-In-Picture not supported for r=" + r);
7587                 }
7588 
7589                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7590                 // current bounds.
7591                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7592                 final Rect bounds = (pinnedStack != null)
7593                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7594 
7595                 mStackSupervisor.moveActivityToPinnedStackLocked(
7596                         r, "enterPictureInPictureMode", bounds);
7597             }
7598         } finally {
7599             Binder.restoreCallingIdentity(origId);
7600         }
7601     }
7602 
7603     // =========================================================
7604     // PROCESS INFO
7605     // =========================================================
7606 
7607     static class ProcessInfoService extends IProcessInfoService.Stub {
7608         final ActivityManagerService mActivityManagerService;
7609         ProcessInfoService(ActivityManagerService activityManagerService) {
7610             mActivityManagerService = activityManagerService;
7611         }
7612 
7613         @Override
7614         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7615             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7616                     /*in*/ pids, /*out*/ states, null);
7617         }
7618 
7619         @Override
7620         public void getProcessStatesAndOomScoresFromPids(
7621                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7622             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7623                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7624         }
7625     }
7626 
7627     /**
7628      * For each PID in the given input array, write the current process state
7629      * for that process into the states array, or -1 to indicate that no
7630      * process with the given PID exists. If scores array is provided, write
7631      * the oom score for the process into the scores array, with INVALID_ADJ
7632      * indicating the PID doesn't exist.
7633      */
7634     public void getProcessStatesAndOomScoresForPIDs(
7635             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7636         if (scores != null) {
7637             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7638                     "getProcessStatesAndOomScoresForPIDs()");
7639         }
7640 
7641         if (pids == null) {
7642             throw new NullPointerException("pids");
7643         } else if (states == null) {
7644             throw new NullPointerException("states");
7645         } else if (pids.length != states.length) {
7646             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7647         } else if (scores != null && pids.length != scores.length) {
7648             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7649         }
7650 
7651         synchronized (mPidsSelfLocked) {
7652             for (int i = 0; i < pids.length; i++) {
7653                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7654                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7655                         pr.curProcState;
7656                 if (scores != null) {
7657                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7658                 }
7659             }
7660         }
7661     }
7662 
7663     // =========================================================
7664     // PERMISSIONS
7665     // =========================================================
7666 
7667     static class PermissionController extends IPermissionController.Stub {
7668         ActivityManagerService mActivityManagerService;
7669         PermissionController(ActivityManagerService activityManagerService) {
7670             mActivityManagerService = activityManagerService;
7671         }
7672 
7673         @Override
7674         public boolean checkPermission(String permission, int pid, int uid) {
7675             return mActivityManagerService.checkPermission(permission, pid,
7676                     uid) == PackageManager.PERMISSION_GRANTED;
7677         }
7678 
7679         @Override
7680         public String[] getPackagesForUid(int uid) {
7681             return mActivityManagerService.mContext.getPackageManager()
7682                     .getPackagesForUid(uid);
7683         }
7684 
7685         @Override
7686         public boolean isRuntimePermission(String permission) {
7687             try {
7688                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7689                         .getPermissionInfo(permission, 0);
7690                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7691             } catch (NameNotFoundException nnfe) {
7692                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7693             }
7694             return false;
7695         }
7696     }
7697 
7698     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7699         @Override
7700         public int checkComponentPermission(String permission, int pid, int uid,
7701                 int owningUid, boolean exported) {
7702             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7703                     owningUid, exported);
7704         }
7705 
7706         @Override
7707         public Object getAMSLock() {
7708             return ActivityManagerService.this;
7709         }
7710     }
7711 
7712     /**
7713      * This can be called with or without the global lock held.
7714      */
7715     int checkComponentPermission(String permission, int pid, int uid,
7716             int owningUid, boolean exported) {
7717         if (pid == MY_PID) {
7718             return PackageManager.PERMISSION_GRANTED;
7719         }
7720         return ActivityManager.checkComponentPermission(permission, uid,
7721                 owningUid, exported);
7722     }
7723 
7724     /**
7725      * As the only public entry point for permissions checking, this method
7726      * can enforce the semantic that requesting a check on a null global
7727      * permission is automatically denied.  (Internally a null permission
7728      * string is used when calling {@link #checkComponentPermission} in cases
7729      * when only uid-based security is needed.)
7730      *
7731      * This can be called with or without the global lock held.
7732      */
7733     @Override
7734     public int checkPermission(String permission, int pid, int uid) {
7735         if (permission == null) {
7736             return PackageManager.PERMISSION_DENIED;
7737         }
7738         return checkComponentPermission(permission, pid, uid, -1, true);
7739     }
7740 
7741     @Override
7742     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7743         if (permission == null) {
7744             return PackageManager.PERMISSION_DENIED;
7745         }
7746 
7747         // We might be performing an operation on behalf of an indirect binder
7748         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7749         // client identity accordingly before proceeding.
7750         Identity tlsIdentity = sCallerIdentity.get();
7751         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7752             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7753                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7754             uid = tlsIdentity.uid;
7755             pid = tlsIdentity.pid;
7756         }
7757 
7758         return checkComponentPermission(permission, pid, uid, -1, true);
7759     }
7760 
7761     /**
7762      * Binder IPC calls go through the public entry point.
7763      * This can be called with or without the global lock held.
7764      */
7765     int checkCallingPermission(String permission) {
7766         return checkPermission(permission,
7767                 Binder.getCallingPid(),
7768                 UserHandle.getAppId(Binder.getCallingUid()));
7769     }
7770 
7771     /**
7772      * This can be called with or without the global lock held.
7773      */
7774     void enforceCallingPermission(String permission, String func) {
7775         if (checkCallingPermission(permission)
7776                 == PackageManager.PERMISSION_GRANTED) {
7777             return;
7778         }
7779 
7780         String msg = "Permission Denial: " + func + " from pid="
7781                 + Binder.getCallingPid()
7782                 + ", uid=" + Binder.getCallingUid()
7783                 + " requires " + permission;
7784         Slog.w(TAG, msg);
7785         throw new SecurityException(msg);
7786     }
7787 
7788     /**
7789      * Determine if UID is holding permissions required to access {@link Uri} in
7790      * the given {@link ProviderInfo}. Final permission checking is always done
7791      * in {@link ContentProvider}.
7792      */
7793     private final boolean checkHoldingPermissionsLocked(
7794             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7795         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7796                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7797         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7798             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7799                     != PERMISSION_GRANTED) {
7800                 return false;
7801             }
7802         }
7803         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7804     }
7805 
7806     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7807             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7808         if (pi.applicationInfo.uid == uid) {
7809             return true;
7810         } else if (!pi.exported) {
7811             return false;
7812         }
7813 
7814         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7815         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7816         try {
7817             // check if target holds top-level <provider> permissions
7818             if (!readMet && pi.readPermission != null && considerUidPermissions
7819                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7820                 readMet = true;
7821             }
7822             if (!writeMet && pi.writePermission != null && considerUidPermissions
7823                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7824                 writeMet = true;
7825             }
7826 
7827             // track if unprotected read/write is allowed; any denied
7828             // <path-permission> below removes this ability
7829             boolean allowDefaultRead = pi.readPermission == null;
7830             boolean allowDefaultWrite = pi.writePermission == null;
7831 
7832             // check if target holds any <path-permission> that match uri
7833             final PathPermission[] pps = pi.pathPermissions;
7834             if (pps != null) {
7835                 final String path = grantUri.uri.getPath();
7836                 int i = pps.length;
7837                 while (i > 0 && (!readMet || !writeMet)) {
7838                     i--;
7839                     PathPermission pp = pps[i];
7840                     if (pp.match(path)) {
7841                         if (!readMet) {
7842                             final String pprperm = pp.getReadPermission();
7843                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7844                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7845                                     + ": match=" + pp.match(path)
7846                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7847                             if (pprperm != null) {
7848                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7849                                         == PERMISSION_GRANTED) {
7850                                     readMet = true;
7851                                 } else {
7852                                     allowDefaultRead = false;
7853                                 }
7854                             }
7855                         }
7856                         if (!writeMet) {
7857                             final String ppwperm = pp.getWritePermission();
7858                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7859                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7860                                     + ": match=" + pp.match(path)
7861                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7862                             if (ppwperm != null) {
7863                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7864                                         == PERMISSION_GRANTED) {
7865                                     writeMet = true;
7866                                 } else {
7867                                     allowDefaultWrite = false;
7868                                 }
7869                             }
7870                         }
7871                     }
7872                 }
7873             }
7874 
7875             // grant unprotected <provider> read/write, if not blocked by
7876             // <path-permission> above
7877             if (allowDefaultRead) readMet = true;
7878             if (allowDefaultWrite) writeMet = true;
7879 
7880         } catch (RemoteException e) {
7881             return false;
7882         }
7883 
7884         return readMet && writeMet;
7885     }
7886 
7887     public int getAppStartMode(int uid, String packageName) {
7888         synchronized (this) {
7889             return checkAllowBackgroundLocked(uid, packageName, -1, true);
7890         }
7891     }
7892 
7893     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7894             boolean allowWhenForeground) {
7895         UidRecord uidRec = mActiveUids.get(uid);
7896         if (!mLenientBackgroundCheck) {
7897             if (!allowWhenForeground || uidRec == null
7898                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7899                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7900                         packageName) != AppOpsManager.MODE_ALLOWED) {
7901                     return ActivityManager.APP_START_MODE_DELAYED;
7902                 }
7903             }
7904 
7905         } else if (uidRec == null || uidRec.idle) {
7906             if (callingPid >= 0) {
7907                 ProcessRecord proc;
7908                 synchronized (mPidsSelfLocked) {
7909                     proc = mPidsSelfLocked.get(callingPid);
7910                 }
7911                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7912                     // Whoever is instigating this is in the foreground, so we will allow it
7913                     // to go through.
7914                     return ActivityManager.APP_START_MODE_NORMAL;
7915                 }
7916             }
7917             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7918                     != AppOpsManager.MODE_ALLOWED) {
7919                 return ActivityManager.APP_START_MODE_DELAYED;
7920             }
7921         }
7922         return ActivityManager.APP_START_MODE_NORMAL;
7923     }
7924 
getProviderInfoLocked(String authority, int userHandle, int pmFlags)7925     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7926         ProviderInfo pi = null;
7927         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7928         if (cpr != null) {
7929             pi = cpr.info;
7930         } else {
7931             try {
7932                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7933                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7934                         userHandle);
7935             } catch (RemoteException ex) {
7936             }
7937         }
7938         return pi;
7939     }
7940 
findUriPermissionLocked(int targetUid, GrantUri grantUri)7941     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7942         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7943         if (targetUris != null) {
7944             return targetUris.get(grantUri);
7945         }
7946         return null;
7947     }
7948 
findOrCreateUriPermissionLocked(String sourcePkg, String targetPkg, int targetUid, GrantUri grantUri)7949     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7950             String targetPkg, int targetUid, GrantUri grantUri) {
7951         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7952         if (targetUris == null) {
7953             targetUris = Maps.newArrayMap();
7954             mGrantedUriPermissions.put(targetUid, targetUris);
7955         }
7956 
7957         UriPermission perm = targetUris.get(grantUri);
7958         if (perm == null) {
7959             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7960             targetUris.put(grantUri, perm);
7961         }
7962 
7963         return perm;
7964     }
7965 
checkUriPermissionLocked(GrantUri grantUri, int uid, final int modeFlags)7966     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7967             final int modeFlags) {
7968         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7969         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7970                 : UriPermission.STRENGTH_OWNED;
7971 
7972         // Root gets to do everything.
7973         if (uid == 0) {
7974             return true;
7975         }
7976 
7977         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
7978         if (perms == null) return false;
7979 
7980         // First look for exact match
7981         final UriPermission exactPerm = perms.get(grantUri);
7982         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
7983             return true;
7984         }
7985 
7986         // No exact match, look for prefixes
7987         final int N = perms.size();
7988         for (int i = 0; i < N; i++) {
7989             final UriPermission perm = perms.valueAt(i);
7990             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
7991                     && perm.getStrength(modeFlags) >= minStrength) {
7992                 return true;
7993             }
7994         }
7995 
7996         return false;
7997     }
7998 
7999     /**
8000      * @param uri This uri must NOT contain an embedded userId.
8001      * @param userId The userId in which the uri is to be resolved.
8002      */
8003     @Override
checkUriPermission(Uri uri, int pid, int uid, final int modeFlags, int userId, IBinder callerToken)8004     public int checkUriPermission(Uri uri, int pid, int uid,
8005             final int modeFlags, int userId, IBinder callerToken) {
8006         enforceNotIsolatedCaller("checkUriPermission");
8007 
8008         // Another redirected-binder-call permissions check as in
8009         // {@link checkPermissionWithToken}.
8010         Identity tlsIdentity = sCallerIdentity.get();
8011         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8012             uid = tlsIdentity.uid;
8013             pid = tlsIdentity.pid;
8014         }
8015 
8016         // Our own process gets to do everything.
8017         if (pid == MY_PID) {
8018             return PackageManager.PERMISSION_GRANTED;
8019         }
8020         synchronized (this) {
8021             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8022                     ? PackageManager.PERMISSION_GRANTED
8023                     : PackageManager.PERMISSION_DENIED;
8024         }
8025     }
8026 
8027     /**
8028      * Check if the targetPkg can be granted permission to access uri by
8029      * the callingUid using the given modeFlags.  Throws a security exception
8030      * if callingUid is not allowed to do this.  Returns the uid of the target
8031      * if the URI permission grant should be performed; returns -1 if it is not
8032      * needed (for example targetPkg already has permission to access the URI).
8033      * If you already know the uid of the target, you can supply it in
8034      * lastTargetUid else set that to -1.
8035      */
checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, final int modeFlags, int lastTargetUid)8036     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8037             final int modeFlags, int lastTargetUid) {
8038         if (!Intent.isAccessUriMode(modeFlags)) {
8039             return -1;
8040         }
8041 
8042         if (targetPkg != null) {
8043             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8044                     "Checking grant " + targetPkg + " permission to " + grantUri);
8045         }
8046 
8047         final IPackageManager pm = AppGlobals.getPackageManager();
8048 
8049         // If this is not a content: uri, we can't do anything with it.
8050         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8051             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8052                     "Can't grant URI permission for non-content URI: " + grantUri);
8053             return -1;
8054         }
8055 
8056         final String authority = grantUri.uri.getAuthority();
8057         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8058                 MATCH_DEBUG_TRIAGED_MISSING);
8059         if (pi == null) {
8060             Slog.w(TAG, "No content provider found for permission check: " +
8061                     grantUri.uri.toSafeString());
8062             return -1;
8063         }
8064 
8065         int targetUid = lastTargetUid;
8066         if (targetUid < 0 && targetPkg != null) {
8067             try {
8068                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8069                         UserHandle.getUserId(callingUid));
8070                 if (targetUid < 0) {
8071                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8072                             "Can't grant URI permission no uid for: " + targetPkg);
8073                     return -1;
8074                 }
8075             } catch (RemoteException ex) {
8076                 return -1;
8077             }
8078         }
8079 
8080         if (targetUid >= 0) {
8081             // First...  does the target actually need this permission?
8082             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8083                 // No need to grant the target this permission.
8084                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8085                         "Target " + targetPkg + " already has full permission to " + grantUri);
8086                 return -1;
8087             }
8088         } else {
8089             // First...  there is no target package, so can anyone access it?
8090             boolean allowed = pi.exported;
8091             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8092                 if (pi.readPermission != null) {
8093                     allowed = false;
8094                 }
8095             }
8096             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8097                 if (pi.writePermission != null) {
8098                     allowed = false;
8099                 }
8100             }
8101             if (allowed) {
8102                 return -1;
8103             }
8104         }
8105 
8106         /* There is a special cross user grant if:
8107          * - The target is on another user.
8108          * - Apps on the current user can access the uri without any uid permissions.
8109          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8110          * grant uri permissions.
8111          */
8112         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8113                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8114                 modeFlags, false /*without considering the uid permissions*/);
8115 
8116         // Second...  is the provider allowing granting of URI permissions?
8117         if (!specialCrossUserGrant) {
8118             if (!pi.grantUriPermissions) {
8119                 throw new SecurityException("Provider " + pi.packageName
8120                         + "/" + pi.name
8121                         + " does not allow granting of Uri permissions (uri "
8122                         + grantUri + ")");
8123             }
8124             if (pi.uriPermissionPatterns != null) {
8125                 final int N = pi.uriPermissionPatterns.length;
8126                 boolean allowed = false;
8127                 for (int i=0; i<N; i++) {
8128                     if (pi.uriPermissionPatterns[i] != null
8129                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8130                         allowed = true;
8131                         break;
8132                     }
8133                 }
8134                 if (!allowed) {
8135                     throw new SecurityException("Provider " + pi.packageName
8136                             + "/" + pi.name
8137                             + " does not allow granting of permission to path of Uri "
8138                             + grantUri);
8139                 }
8140             }
8141         }
8142 
8143         // Third...  does the caller itself have permission to access
8144         // this uri?
8145         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8146             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8147                 // Require they hold a strong enough Uri permission
8148                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8149                     throw new SecurityException("Uid " + callingUid
8150                             + " does not have permission to uri " + grantUri);
8151                 }
8152             }
8153         }
8154         return targetUid;
8155     }
8156 
8157     /**
8158      * @param uri This uri must NOT contain an embedded userId.
8159      * @param userId The userId in which the uri is to be resolved.
8160      */
8161     @Override
checkGrantUriPermission(int callingUid, String targetPkg, Uri uri, final int modeFlags, int userId)8162     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8163             final int modeFlags, int userId) {
8164         enforceNotIsolatedCaller("checkGrantUriPermission");
8165         synchronized(this) {
8166             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8167                     new GrantUri(userId, uri, false), modeFlags, -1);
8168         }
8169     }
8170 
grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri, final int modeFlags, UriPermissionOwner owner)8171     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8172             final int modeFlags, UriPermissionOwner owner) {
8173         if (!Intent.isAccessUriMode(modeFlags)) {
8174             return;
8175         }
8176 
8177         // So here we are: the caller has the assumed permission
8178         // to the uri, and the target doesn't.  Let's now give this to
8179         // the target.
8180 
8181         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8182                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8183 
8184         final String authority = grantUri.uri.getAuthority();
8185         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8186                 MATCH_DEBUG_TRIAGED_MISSING);
8187         if (pi == null) {
8188             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8189             return;
8190         }
8191 
8192         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8193             grantUri.prefix = true;
8194         }
8195         final UriPermission perm = findOrCreateUriPermissionLocked(
8196                 pi.packageName, targetPkg, targetUid, grantUri);
8197         perm.grantModes(modeFlags, owner);
8198     }
8199 
grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri, final int modeFlags, UriPermissionOwner owner, int targetUserId)8200     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8201             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8202         if (targetPkg == null) {
8203             throw new NullPointerException("targetPkg");
8204         }
8205         int targetUid;
8206         final IPackageManager pm = AppGlobals.getPackageManager();
8207         try {
8208             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8209         } catch (RemoteException ex) {
8210             return;
8211         }
8212 
8213         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8214                 targetUid);
8215         if (targetUid < 0) {
8216             return;
8217         }
8218 
8219         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8220                 owner);
8221     }
8222 
8223     static class NeededUriGrants extends ArrayList<GrantUri> {
8224         final String targetPkg;
8225         final int targetUid;
8226         final int flags;
8227 
NeededUriGrants(String targetPkg, int targetUid, int flags)8228         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8229             this.targetPkg = targetPkg;
8230             this.targetUid = targetUid;
8231             this.flags = flags;
8232         }
8233     }
8234 
8235     /**
8236      * Like checkGrantUriPermissionLocked, but takes an Intent.
8237      */
checkGrantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId)8238     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8239             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8240         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8241                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8242                 + " clip=" + (intent != null ? intent.getClipData() : null)
8243                 + " from " + intent + "; flags=0x"
8244                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8245 
8246         if (targetPkg == null) {
8247             throw new NullPointerException("targetPkg");
8248         }
8249 
8250         if (intent == null) {
8251             return null;
8252         }
8253         Uri data = intent.getData();
8254         ClipData clip = intent.getClipData();
8255         if (data == null && clip == null) {
8256             return null;
8257         }
8258         // Default userId for uris in the intent (if they don't specify it themselves)
8259         int contentUserHint = intent.getContentUserHint();
8260         if (contentUserHint == UserHandle.USER_CURRENT) {
8261             contentUserHint = UserHandle.getUserId(callingUid);
8262         }
8263         final IPackageManager pm = AppGlobals.getPackageManager();
8264         int targetUid;
8265         if (needed != null) {
8266             targetUid = needed.targetUid;
8267         } else {
8268             try {
8269                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8270                         targetUserId);
8271             } catch (RemoteException ex) {
8272                 return null;
8273             }
8274             if (targetUid < 0) {
8275                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8276                         "Can't grant URI permission no uid for: " + targetPkg
8277                         + " on user " + targetUserId);
8278                 return null;
8279             }
8280         }
8281         if (data != null) {
8282             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8283             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8284                     targetUid);
8285             if (targetUid > 0) {
8286                 if (needed == null) {
8287                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8288                 }
8289                 needed.add(grantUri);
8290             }
8291         }
8292         if (clip != null) {
8293             for (int i=0; i<clip.getItemCount(); i++) {
8294                 Uri uri = clip.getItemAt(i).getUri();
8295                 if (uri != null) {
8296                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8297                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8298                             targetUid);
8299                     if (targetUid > 0) {
8300                         if (needed == null) {
8301                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8302                         }
8303                         needed.add(grantUri);
8304                     }
8305                 } else {
8306                     Intent clipIntent = clip.getItemAt(i).getIntent();
8307                     if (clipIntent != null) {
8308                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8309                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8310                         if (newNeeded != null) {
8311                             needed = newNeeded;
8312                         }
8313                     }
8314                 }
8315             }
8316         }
8317 
8318         return needed;
8319     }
8320 
8321     /**
8322      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8323      */
grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed, UriPermissionOwner owner)8324     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8325             UriPermissionOwner owner) {
8326         if (needed != null) {
8327             for (int i=0; i<needed.size(); i++) {
8328                 GrantUri grantUri = needed.get(i);
8329                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8330                         grantUri, needed.flags, owner);
8331             }
8332         }
8333     }
8334 
grantUriPermissionFromIntentLocked(int callingUid, String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId)8335     void grantUriPermissionFromIntentLocked(int callingUid,
8336             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8337         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8338                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8339         if (needed == null) {
8340             return;
8341         }
8342 
8343         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8344     }
8345 
8346     /**
8347      * @param uri This uri must NOT contain an embedded userId.
8348      * @param userId The userId in which the uri is to be resolved.
8349      */
8350     @Override
grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri, final int modeFlags, int userId)8351     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8352             final int modeFlags, int userId) {
8353         enforceNotIsolatedCaller("grantUriPermission");
8354         GrantUri grantUri = new GrantUri(userId, uri, false);
8355         synchronized(this) {
8356             final ProcessRecord r = getRecordForAppLocked(caller);
8357             if (r == null) {
8358                 throw new SecurityException("Unable to find app for caller "
8359                         + caller
8360                         + " when granting permission to uri " + grantUri);
8361             }
8362             if (targetPkg == null) {
8363                 throw new IllegalArgumentException("null target");
8364             }
8365             if (grantUri == null) {
8366                 throw new IllegalArgumentException("null uri");
8367             }
8368 
8369             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8370                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8371                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8372                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8373 
8374             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8375                     UserHandle.getUserId(r.uid));
8376         }
8377     }
8378 
removeUriPermissionIfNeededLocked(UriPermission perm)8379     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8380         if (perm.modeFlags == 0) {
8381             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8382                     perm.targetUid);
8383             if (perms != null) {
8384                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8385                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8386 
8387                 perms.remove(perm.uri);
8388                 if (perms.isEmpty()) {
8389                     mGrantedUriPermissions.remove(perm.targetUid);
8390                 }
8391             }
8392         }
8393     }
8394 
revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags)8395     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8396         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8397                 "Revoking all granted permissions to " + grantUri);
8398 
8399         final IPackageManager pm = AppGlobals.getPackageManager();
8400         final String authority = grantUri.uri.getAuthority();
8401         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8402                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8403         if (pi == null) {
8404             Slog.w(TAG, "No content provider found for permission revoke: "
8405                     + grantUri.toSafeString());
8406             return;
8407         }
8408 
8409         // Does the caller have this permission on the URI?
8410         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8411             // If they don't have direct access to the URI, then revoke any
8412             // ownerless URI permissions that have been granted to them.
8413             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8414             if (perms != null) {
8415                 boolean persistChanged = false;
8416                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8417                     final UriPermission perm = it.next();
8418                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8419                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8420                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8421                                 "Revoking non-owned " + perm.targetUid
8422                                 + " permission to " + perm.uri);
8423                         persistChanged |= perm.revokeModes(
8424                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8425                         if (perm.modeFlags == 0) {
8426                             it.remove();
8427                         }
8428                     }
8429                 }
8430                 if (perms.isEmpty()) {
8431                     mGrantedUriPermissions.remove(callingUid);
8432                 }
8433                 if (persistChanged) {
8434                     schedulePersistUriGrants();
8435                 }
8436             }
8437             return;
8438         }
8439 
8440         boolean persistChanged = false;
8441 
8442         // Go through all of the permissions and remove any that match.
8443         int N = mGrantedUriPermissions.size();
8444         for (int i = 0; i < N; i++) {
8445             final int targetUid = mGrantedUriPermissions.keyAt(i);
8446             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8447 
8448             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8449                 final UriPermission perm = it.next();
8450                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8451                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8452                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8453                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8454                     persistChanged |= perm.revokeModes(
8455                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8456                     if (perm.modeFlags == 0) {
8457                         it.remove();
8458                     }
8459                 }
8460             }
8461 
8462             if (perms.isEmpty()) {
8463                 mGrantedUriPermissions.remove(targetUid);
8464                 N--;
8465                 i--;
8466             }
8467         }
8468 
8469         if (persistChanged) {
8470             schedulePersistUriGrants();
8471         }
8472     }
8473 
8474     /**
8475      * @param uri This uri must NOT contain an embedded userId.
8476      * @param userId The userId in which the uri is to be resolved.
8477      */
8478     @Override
revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags, int userId)8479     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8480             int userId) {
8481         enforceNotIsolatedCaller("revokeUriPermission");
8482         synchronized(this) {
8483             final ProcessRecord r = getRecordForAppLocked(caller);
8484             if (r == null) {
8485                 throw new SecurityException("Unable to find app for caller "
8486                         + caller
8487                         + " when revoking permission to uri " + uri);
8488             }
8489             if (uri == null) {
8490                 Slog.w(TAG, "revokeUriPermission: null uri");
8491                 return;
8492             }
8493 
8494             if (!Intent.isAccessUriMode(modeFlags)) {
8495                 return;
8496             }
8497 
8498             final String authority = uri.getAuthority();
8499             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8500                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8501             if (pi == null) {
8502                 Slog.w(TAG, "No content provider found for permission revoke: "
8503                         + uri.toSafeString());
8504                 return;
8505             }
8506 
8507             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8508         }
8509     }
8510 
8511     /**
8512      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8513      * given package.
8514      *
8515      * @param packageName Package name to match, or {@code null} to apply to all
8516      *            packages.
8517      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8518      *            to all users.
8519      * @param persistable If persistable grants should be removed.
8520      */
removeUriPermissionsForPackageLocked( String packageName, int userHandle, boolean persistable)8521     private void removeUriPermissionsForPackageLocked(
8522             String packageName, int userHandle, boolean persistable) {
8523         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8524             throw new IllegalArgumentException("Must narrow by either package or user");
8525         }
8526 
8527         boolean persistChanged = false;
8528 
8529         int N = mGrantedUriPermissions.size();
8530         for (int i = 0; i < N; i++) {
8531             final int targetUid = mGrantedUriPermissions.keyAt(i);
8532             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8533 
8534             // Only inspect grants matching user
8535             if (userHandle == UserHandle.USER_ALL
8536                     || userHandle == UserHandle.getUserId(targetUid)) {
8537                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8538                     final UriPermission perm = it.next();
8539 
8540                     // Only inspect grants matching package
8541                     if (packageName == null || perm.sourcePkg.equals(packageName)
8542                             || perm.targetPkg.equals(packageName)) {
8543                         persistChanged |= perm.revokeModes(persistable
8544                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8545 
8546                         // Only remove when no modes remain; any persisted grants
8547                         // will keep this alive.
8548                         if (perm.modeFlags == 0) {
8549                             it.remove();
8550                         }
8551                     }
8552                 }
8553 
8554                 if (perms.isEmpty()) {
8555                     mGrantedUriPermissions.remove(targetUid);
8556                     N--;
8557                     i--;
8558                 }
8559             }
8560         }
8561 
8562         if (persistChanged) {
8563             schedulePersistUriGrants();
8564         }
8565     }
8566 
8567     @Override
newUriPermissionOwner(String name)8568     public IBinder newUriPermissionOwner(String name) {
8569         enforceNotIsolatedCaller("newUriPermissionOwner");
8570         synchronized(this) {
8571             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8572             return owner.getExternalTokenLocked();
8573         }
8574     }
8575 
8576     @Override
getUriPermissionOwnerForActivity(IBinder activityToken)8577     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8578         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8579         synchronized(this) {
8580             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8581             if (r == null) {
8582                 throw new IllegalArgumentException("Activity does not exist; token="
8583                         + activityToken);
8584             }
8585             return r.getUriPermissionsLocked().getExternalTokenLocked();
8586         }
8587     }
8588     /**
8589      * @param uri This uri must NOT contain an embedded userId.
8590      * @param sourceUserId The userId in which the uri is to be resolved.
8591      * @param targetUserId The userId of the app that receives the grant.
8592      */
8593     @Override
grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri, final int modeFlags, int sourceUserId, int targetUserId)8594     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8595             final int modeFlags, int sourceUserId, int targetUserId) {
8596         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8597                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8598                 "grantUriPermissionFromOwner", null);
8599         synchronized(this) {
8600             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8601             if (owner == null) {
8602                 throw new IllegalArgumentException("Unknown owner: " + token);
8603             }
8604             if (fromUid != Binder.getCallingUid()) {
8605                 if (Binder.getCallingUid() != Process.myUid()) {
8606                     // Only system code can grant URI permissions on behalf
8607                     // of other users.
8608                     throw new SecurityException("nice try");
8609                 }
8610             }
8611             if (targetPkg == null) {
8612                 throw new IllegalArgumentException("null target");
8613             }
8614             if (uri == null) {
8615                 throw new IllegalArgumentException("null uri");
8616             }
8617 
8618             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8619                     modeFlags, owner, targetUserId);
8620         }
8621     }
8622 
8623     /**
8624      * @param uri This uri must NOT contain an embedded userId.
8625      * @param userId The userId in which the uri is to be resolved.
8626      */
8627     @Override
revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId)8628     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8629         synchronized(this) {
8630             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8631             if (owner == null) {
8632                 throw new IllegalArgumentException("Unknown owner: " + token);
8633             }
8634 
8635             if (uri == null) {
8636                 owner.removeUriPermissionsLocked(mode);
8637             } else {
8638                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8639                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8640             }
8641         }
8642     }
8643 
schedulePersistUriGrants()8644     private void schedulePersistUriGrants() {
8645         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8646             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8647                     10 * DateUtils.SECOND_IN_MILLIS);
8648         }
8649     }
8650 
writeGrantedUriPermissions()8651     private void writeGrantedUriPermissions() {
8652         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8653 
8654         // Snapshot permissions so we can persist without lock
8655         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8656         synchronized (this) {
8657             final int size = mGrantedUriPermissions.size();
8658             for (int i = 0; i < size; i++) {
8659                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8660                 for (UriPermission perm : perms.values()) {
8661                     if (perm.persistedModeFlags != 0) {
8662                         persist.add(perm.snapshot());
8663                     }
8664                 }
8665             }
8666         }
8667 
8668         FileOutputStream fos = null;
8669         try {
8670             fos = mGrantFile.startWrite();
8671 
8672             XmlSerializer out = new FastXmlSerializer();
8673             out.setOutput(fos, StandardCharsets.UTF_8.name());
8674             out.startDocument(null, true);
8675             out.startTag(null, TAG_URI_GRANTS);
8676             for (UriPermission.Snapshot perm : persist) {
8677                 out.startTag(null, TAG_URI_GRANT);
8678                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8679                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8680                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8681                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8682                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8683                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8684                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8685                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8686                 out.endTag(null, TAG_URI_GRANT);
8687             }
8688             out.endTag(null, TAG_URI_GRANTS);
8689             out.endDocument();
8690 
8691             mGrantFile.finishWrite(fos);
8692         } catch (IOException e) {
8693             if (fos != null) {
8694                 mGrantFile.failWrite(fos);
8695             }
8696         }
8697     }
8698 
readGrantedUriPermissionsLocked()8699     private void readGrantedUriPermissionsLocked() {
8700         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8701 
8702         final long now = System.currentTimeMillis();
8703 
8704         FileInputStream fis = null;
8705         try {
8706             fis = mGrantFile.openRead();
8707             final XmlPullParser in = Xml.newPullParser();
8708             in.setInput(fis, StandardCharsets.UTF_8.name());
8709 
8710             int type;
8711             while ((type = in.next()) != END_DOCUMENT) {
8712                 final String tag = in.getName();
8713                 if (type == START_TAG) {
8714                     if (TAG_URI_GRANT.equals(tag)) {
8715                         final int sourceUserId;
8716                         final int targetUserId;
8717                         final int userHandle = readIntAttribute(in,
8718                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8719                         if (userHandle != UserHandle.USER_NULL) {
8720                             // For backwards compatibility.
8721                             sourceUserId = userHandle;
8722                             targetUserId = userHandle;
8723                         } else {
8724                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8725                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8726                         }
8727                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8728                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8729                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8730                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8731                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8732                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8733 
8734                         // Sanity check that provider still belongs to source package
8735                         // Both direct boot aware and unaware packages are fine as we
8736                         // will do filtering at query time to avoid multiple parsing.
8737                         final ProviderInfo pi = getProviderInfoLocked(
8738                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8739                                         | MATCH_DIRECT_BOOT_UNAWARE);
8740                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8741                             int targetUid = -1;
8742                             try {
8743                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8744                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8745                             } catch (RemoteException e) {
8746                             }
8747                             if (targetUid != -1) {
8748                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8749                                         sourcePkg, targetPkg, targetUid,
8750                                         new GrantUri(sourceUserId, uri, prefix));
8751                                 perm.initPersistedModes(modeFlags, createdTime);
8752                             }
8753                         } else {
8754                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8755                                     + " but instead found " + pi);
8756                         }
8757                     }
8758                 }
8759             }
8760         } catch (FileNotFoundException e) {
8761             // Missing grants is okay
8762         } catch (IOException e) {
8763             Slog.wtf(TAG, "Failed reading Uri grants", e);
8764         } catch (XmlPullParserException e) {
8765             Slog.wtf(TAG, "Failed reading Uri grants", e);
8766         } finally {
8767             IoUtils.closeQuietly(fis);
8768         }
8769     }
8770 
8771     /**
8772      * @param uri This uri must NOT contain an embedded userId.
8773      * @param userId The userId in which the uri is to be resolved.
8774      */
8775     @Override
takePersistableUriPermission(Uri uri, final int modeFlags, int userId)8776     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8777         enforceNotIsolatedCaller("takePersistableUriPermission");
8778 
8779         Preconditions.checkFlagsArgument(modeFlags,
8780                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8781 
8782         synchronized (this) {
8783             final int callingUid = Binder.getCallingUid();
8784             boolean persistChanged = false;
8785             GrantUri grantUri = new GrantUri(userId, uri, false);
8786 
8787             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8788                     new GrantUri(userId, uri, false));
8789             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8790                     new GrantUri(userId, uri, true));
8791 
8792             final boolean exactValid = (exactPerm != null)
8793                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8794             final boolean prefixValid = (prefixPerm != null)
8795                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8796 
8797             if (!(exactValid || prefixValid)) {
8798                 throw new SecurityException("No persistable permission grants found for UID "
8799                         + callingUid + " and Uri " + grantUri.toSafeString());
8800             }
8801 
8802             if (exactValid) {
8803                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8804             }
8805             if (prefixValid) {
8806                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8807             }
8808 
8809             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8810 
8811             if (persistChanged) {
8812                 schedulePersistUriGrants();
8813             }
8814         }
8815     }
8816 
8817     /**
8818      * @param uri This uri must NOT contain an embedded userId.
8819      * @param userId The userId in which the uri is to be resolved.
8820      */
8821     @Override
releasePersistableUriPermission(Uri uri, final int modeFlags, int userId)8822     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8823         enforceNotIsolatedCaller("releasePersistableUriPermission");
8824 
8825         Preconditions.checkFlagsArgument(modeFlags,
8826                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8827 
8828         synchronized (this) {
8829             final int callingUid = Binder.getCallingUid();
8830             boolean persistChanged = false;
8831 
8832             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8833                     new GrantUri(userId, uri, false));
8834             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8835                     new GrantUri(userId, uri, true));
8836             if (exactPerm == null && prefixPerm == null) {
8837                 throw new SecurityException("No permission grants found for UID " + callingUid
8838                         + " and Uri " + uri.toSafeString());
8839             }
8840 
8841             if (exactPerm != null) {
8842                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8843                 removeUriPermissionIfNeededLocked(exactPerm);
8844             }
8845             if (prefixPerm != null) {
8846                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8847                 removeUriPermissionIfNeededLocked(prefixPerm);
8848             }
8849 
8850             if (persistChanged) {
8851                 schedulePersistUriGrants();
8852             }
8853         }
8854     }
8855 
8856     /**
8857      * Prune any older {@link UriPermission} for the given UID until outstanding
8858      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8859      *
8860      * @return if any mutations occured that require persisting.
8861      */
maybePrunePersistedUriGrantsLocked(int uid)8862     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8863         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8864         if (perms == null) return false;
8865         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8866 
8867         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8868         for (UriPermission perm : perms.values()) {
8869             if (perm.persistedModeFlags != 0) {
8870                 persisted.add(perm);
8871             }
8872         }
8873 
8874         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8875         if (trimCount <= 0) return false;
8876 
8877         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8878         for (int i = 0; i < trimCount; i++) {
8879             final UriPermission perm = persisted.get(i);
8880 
8881             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8882                     "Trimming grant created at " + perm.persistedCreateTime);
8883 
8884             perm.releasePersistableModes(~0);
8885             removeUriPermissionIfNeededLocked(perm);
8886         }
8887 
8888         return true;
8889     }
8890 
8891     @Override
getPersistedUriPermissions( String packageName, boolean incoming)8892     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8893             String packageName, boolean incoming) {
8894         enforceNotIsolatedCaller("getPersistedUriPermissions");
8895         Preconditions.checkNotNull(packageName, "packageName");
8896 
8897         final int callingUid = Binder.getCallingUid();
8898         final int callingUserId = UserHandle.getUserId(callingUid);
8899         final IPackageManager pm = AppGlobals.getPackageManager();
8900         try {
8901             final int packageUid = pm.getPackageUid(packageName,
8902                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8903             if (packageUid != callingUid) {
8904                 throw new SecurityException(
8905                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8906             }
8907         } catch (RemoteException e) {
8908             throw new SecurityException("Failed to verify package name ownership");
8909         }
8910 
8911         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8912         synchronized (this) {
8913             if (incoming) {
8914                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8915                         callingUid);
8916                 if (perms == null) {
8917                     Slog.w(TAG, "No permission grants found for " + packageName);
8918                 } else {
8919                     for (UriPermission perm : perms.values()) {
8920                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8921                             result.add(perm.buildPersistedPublicApiObject());
8922                         }
8923                     }
8924                 }
8925             } else {
8926                 final int size = mGrantedUriPermissions.size();
8927                 for (int i = 0; i < size; i++) {
8928                     final ArrayMap<GrantUri, UriPermission> perms =
8929                             mGrantedUriPermissions.valueAt(i);
8930                     for (UriPermission perm : perms.values()) {
8931                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8932                             result.add(perm.buildPersistedPublicApiObject());
8933                         }
8934                     }
8935                 }
8936             }
8937         }
8938         return new ParceledListSlice<android.content.UriPermission>(result);
8939     }
8940 
8941     @Override
getGrantedUriPermissions( String packageName, int userId)8942     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8943             String packageName, int userId) {
8944         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8945                 "getGrantedUriPermissions");
8946 
8947         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8948         synchronized (this) {
8949             final int size = mGrantedUriPermissions.size();
8950             for (int i = 0; i < size; i++) {
8951                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8952                 for (UriPermission perm : perms.values()) {
8953                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8954                             && perm.persistedModeFlags != 0) {
8955                         result.add(perm.buildPersistedPublicApiObject());
8956                     }
8957                 }
8958             }
8959         }
8960         return new ParceledListSlice<android.content.UriPermission>(result);
8961     }
8962 
8963     @Override
clearGrantedUriPermissions(String packageName, int userId)8964     public void clearGrantedUriPermissions(String packageName, int userId) {
8965         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8966                 "clearGrantedUriPermissions");
8967         removeUriPermissionsForPackageLocked(packageName, userId, true);
8968     }
8969 
8970     @Override
showWaitingForDebugger(IApplicationThread who, boolean waiting)8971     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
8972         synchronized (this) {
8973             ProcessRecord app =
8974                 who != null ? getRecordForAppLocked(who) : null;
8975             if (app == null) return;
8976 
8977             Message msg = Message.obtain();
8978             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
8979             msg.obj = app;
8980             msg.arg1 = waiting ? 1 : 0;
8981             mUiHandler.sendMessage(msg);
8982         }
8983     }
8984 
8985     @Override
getMemoryInfo(ActivityManager.MemoryInfo outInfo)8986     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
8987         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
8988         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
8989         outInfo.availMem = Process.getFreeMemory();
8990         outInfo.totalMem = Process.getTotalMemory();
8991         outInfo.threshold = homeAppMem;
8992         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
8993         outInfo.hiddenAppThreshold = cachedAppMem;
8994         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
8995                 ProcessList.SERVICE_ADJ);
8996         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
8997                 ProcessList.VISIBLE_APP_ADJ);
8998         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
8999                 ProcessList.FOREGROUND_APP_ADJ);
9000     }
9001 
9002     // =========================================================
9003     // TASK MANAGEMENT
9004     // =========================================================
9005 
9006     @Override
9007     public List<IAppTask> getAppTasks(String callingPackage) {
9008         int callingUid = Binder.getCallingUid();
9009         long ident = Binder.clearCallingIdentity();
9010 
9011         synchronized(this) {
9012             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9013             try {
9014                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9015 
9016                 final int N = mRecentTasks.size();
9017                 for (int i = 0; i < N; i++) {
9018                     TaskRecord tr = mRecentTasks.get(i);
9019                     // Skip tasks that do not match the caller.  We don't need to verify
9020                     // callingPackage, because we are also limiting to callingUid and know
9021                     // that will limit to the correct security sandbox.
9022                     if (tr.effectiveUid != callingUid) {
9023                         continue;
9024                     }
9025                     Intent intent = tr.getBaseIntent();
9026                     if (intent == null ||
9027                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9028                         continue;
9029                     }
9030                     ActivityManager.RecentTaskInfo taskInfo =
9031                             createRecentTaskInfoFromTaskRecord(tr);
9032                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9033                     list.add(taskImpl);
9034                 }
9035             } finally {
9036                 Binder.restoreCallingIdentity(ident);
9037             }
9038             return list;
9039         }
9040     }
9041 
9042     @Override
9043     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9044         final int callingUid = Binder.getCallingUid();
9045         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9046 
9047         synchronized(this) {
9048             if (DEBUG_ALL) Slog.v(
9049                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9050 
9051             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9052                     callingUid);
9053 
9054             // TODO: Improve with MRU list from all ActivityStacks.
9055             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9056         }
9057 
9058         return list;
9059     }
9060 
9061     /**
9062      * Creates a new RecentTaskInfo from a TaskRecord.
9063      */
9064     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9065         // Update the task description to reflect any changes in the task stack
9066         tr.updateTaskDescription();
9067 
9068         // Compose the recent task info
9069         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9070         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9071         rti.persistentId = tr.taskId;
9072         rti.baseIntent = new Intent(tr.getBaseIntent());
9073         rti.origActivity = tr.origActivity;
9074         rti.realActivity = tr.realActivity;
9075         rti.description = tr.lastDescription;
9076         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9077         rti.userId = tr.userId;
9078         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9079         rti.firstActiveTime = tr.firstActiveTime;
9080         rti.lastActiveTime = tr.lastActiveTime;
9081         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9082         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9083         rti.numActivities = 0;
9084         if (tr.mBounds != null) {
9085             rti.bounds = new Rect(tr.mBounds);
9086         }
9087         rti.isDockable = tr.canGoInDockedStack();
9088         rti.resizeMode = tr.mResizeMode;
9089 
9090         ActivityRecord base = null;
9091         ActivityRecord top = null;
9092         ActivityRecord tmp;
9093 
9094         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9095             tmp = tr.mActivities.get(i);
9096             if (tmp.finishing) {
9097                 continue;
9098             }
9099             base = tmp;
9100             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9101                 top = base;
9102             }
9103             rti.numActivities++;
9104         }
9105 
9106         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9107         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9108 
9109         return rti;
9110     }
9111 
9112     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9113         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9114                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9115         if (!allowed) {
9116             if (checkPermission(android.Manifest.permission.GET_TASKS,
9117                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9118                 // Temporary compatibility: some existing apps on the system image may
9119                 // still be requesting the old permission and not switched to the new
9120                 // one; if so, we'll still allow them full access.  This means we need
9121                 // to see if they are holding the old permission and are a system app.
9122                 try {
9123                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9124                         allowed = true;
9125                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9126                                 + " is using old GET_TASKS but privileged; allowing");
9127                     }
9128                 } catch (RemoteException e) {
9129                 }
9130             }
9131         }
9132         if (!allowed) {
9133             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9134                     + " does not hold REAL_GET_TASKS; limiting output");
9135         }
9136         return allowed;
9137     }
9138 
9139     @Override
9140     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9141             int userId) {
9142         final int callingUid = Binder.getCallingUid();
9143         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9144                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9145 
9146         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9147         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9148         synchronized (this) {
9149             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9150                     callingUid);
9151             final boolean detailed = checkCallingPermission(
9152                     android.Manifest.permission.GET_DETAILED_TASKS)
9153                     == PackageManager.PERMISSION_GRANTED;
9154 
9155             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9156                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9157                 return ParceledListSlice.emptyList();
9158             }
9159             mRecentTasks.loadUserRecentsLocked(userId);
9160 
9161             final int recentsCount = mRecentTasks.size();
9162             ArrayList<ActivityManager.RecentTaskInfo> res =
9163                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9164 
9165             final Set<Integer> includedUsers;
9166             if (includeProfiles) {
9167                 includedUsers = mUserController.getProfileIds(userId);
9168             } else {
9169                 includedUsers = new HashSet<>();
9170             }
9171             includedUsers.add(Integer.valueOf(userId));
9172 
9173             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9174                 TaskRecord tr = mRecentTasks.get(i);
9175                 // Only add calling user or related users recent tasks
9176                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9177                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9178                     continue;
9179                 }
9180 
9181                 if (tr.realActivitySuspended) {
9182                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9183                     continue;
9184                 }
9185 
9186                 // Return the entry if desired by the caller.  We always return
9187                 // the first entry, because callers always expect this to be the
9188                 // foreground app.  We may filter others if the caller has
9189                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9190                 // we should exclude the entry.
9191 
9192                 if (i == 0
9193                         || withExcluded
9194                         || (tr.intent == null)
9195                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9196                                 == 0)) {
9197                     if (!allowed) {
9198                         // If the caller doesn't have the GET_TASKS permission, then only
9199                         // allow them to see a small subset of tasks -- their own and home.
9200                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9201                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9202                             continue;
9203                         }
9204                     }
9205                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9206                         if (tr.stack != null && tr.stack.isHomeStack()) {
9207                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9208                                     "Skipping, home stack task: " + tr);
9209                             continue;
9210                         }
9211                     }
9212                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9213                         final ActivityStack stack = tr.stack;
9214                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9215                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9216                                     "Skipping, top task in docked stack: " + tr);
9217                             continue;
9218                         }
9219                     }
9220                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9221                         if (tr.stack != null && tr.stack.isPinnedStack()) {
9222                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9223                                     "Skipping, pinned stack task: " + tr);
9224                             continue;
9225                         }
9226                     }
9227                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9228                         // Don't include auto remove tasks that are finished or finishing.
9229                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9230                                 "Skipping, auto-remove without activity: " + tr);
9231                         continue;
9232                     }
9233                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9234                             && !tr.isAvailable) {
9235                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9236                                 "Skipping, unavail real act: " + tr);
9237                         continue;
9238                     }
9239 
9240                     if (!tr.mUserSetupComplete) {
9241                         // Don't include task launched while user is not done setting-up.
9242                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9243                                 "Skipping, user setup not complete: " + tr);
9244                         continue;
9245                     }
9246 
9247                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9248                     if (!detailed) {
9249                         rti.baseIntent.replaceExtras((Bundle)null);
9250                     }
9251 
9252                     res.add(rti);
9253                     maxNum--;
9254                 }
9255             }
9256             return new ParceledListSlice<>(res);
9257         }
9258     }
9259 
9260     @Override
9261     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9262         synchronized (this) {
9263             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9264                     "getTaskThumbnail()");
9265             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9266                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9267             if (tr != null) {
9268                 return tr.getTaskThumbnailLocked();
9269             }
9270         }
9271         return null;
9272     }
9273 
9274     @Override
9275     public int addAppTask(IBinder activityToken, Intent intent,
9276             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9277         final int callingUid = Binder.getCallingUid();
9278         final long callingIdent = Binder.clearCallingIdentity();
9279 
9280         try {
9281             synchronized (this) {
9282                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9283                 if (r == null) {
9284                     throw new IllegalArgumentException("Activity does not exist; token="
9285                             + activityToken);
9286                 }
9287                 ComponentName comp = intent.getComponent();
9288                 if (comp == null) {
9289                     throw new IllegalArgumentException("Intent " + intent
9290                             + " must specify explicit component");
9291                 }
9292                 if (thumbnail.getWidth() != mThumbnailWidth
9293                         || thumbnail.getHeight() != mThumbnailHeight) {
9294                     throw new IllegalArgumentException("Bad thumbnail size: got "
9295                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9296                             + mThumbnailWidth + "x" + mThumbnailHeight);
9297                 }
9298                 if (intent.getSelector() != null) {
9299                     intent.setSelector(null);
9300                 }
9301                 if (intent.getSourceBounds() != null) {
9302                     intent.setSourceBounds(null);
9303                 }
9304                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9305                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9306                         // The caller has added this as an auto-remove task...  that makes no
9307                         // sense, so turn off auto-remove.
9308                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9309                     }
9310                 }
9311                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9312                     mLastAddedTaskActivity = null;
9313                 }
9314                 ActivityInfo ainfo = mLastAddedTaskActivity;
9315                 if (ainfo == null) {
9316                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9317                             comp, 0, UserHandle.getUserId(callingUid));
9318                     if (ainfo.applicationInfo.uid != callingUid) {
9319                         throw new SecurityException(
9320                                 "Can't add task for another application: target uid="
9321                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9322                     }
9323                 }
9324 
9325                 // Use the full screen as the context for the task thumbnail
9326                 final Point displaySize = new Point();
9327                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9328                 r.task.stack.getDisplaySize(displaySize);
9329                 thumbnailInfo.taskWidth = displaySize.x;
9330                 thumbnailInfo.taskHeight = displaySize.y;
9331                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9332 
9333                 TaskRecord task = new TaskRecord(this,
9334                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9335                         ainfo, intent, description, thumbnailInfo);
9336 
9337                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9338                 if (trimIdx >= 0) {
9339                     // If this would have caused a trim, then we'll abort because that
9340                     // means it would be added at the end of the list but then just removed.
9341                     return INVALID_TASK_ID;
9342                 }
9343 
9344                 final int N = mRecentTasks.size();
9345                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9346                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9347                     tr.removedFromRecents();
9348                 }
9349 
9350                 task.inRecents = true;
9351                 mRecentTasks.add(task);
9352                 r.task.stack.addTask(task, false, "addAppTask");
9353 
9354                 task.setLastThumbnailLocked(thumbnail);
9355                 task.freeLastThumbnail();
9356 
9357                 return task.taskId;
9358             }
9359         } finally {
9360             Binder.restoreCallingIdentity(callingIdent);
9361         }
9362     }
9363 
9364     @Override
getAppTaskThumbnailSize()9365     public Point getAppTaskThumbnailSize() {
9366         synchronized (this) {
9367             return new Point(mThumbnailWidth,  mThumbnailHeight);
9368         }
9369     }
9370 
9371     @Override
setTaskDescription(IBinder token, ActivityManager.TaskDescription td)9372     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9373         synchronized (this) {
9374             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9375             if (r != null) {
9376                 r.setTaskDescription(td);
9377                 r.task.updateTaskDescription();
9378             }
9379         }
9380     }
9381 
9382     @Override
setTaskResizeable(int taskId, int resizeableMode)9383     public void setTaskResizeable(int taskId, int resizeableMode) {
9384         synchronized (this) {
9385             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9386                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9387             if (task == null) {
9388                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9389                 return;
9390             }
9391             if (task.mResizeMode != resizeableMode) {
9392                 task.mResizeMode = resizeableMode;
9393                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9394                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9395                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9396             }
9397         }
9398     }
9399 
9400     @Override
resizeTask(int taskId, Rect bounds, int resizeMode)9401     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9402         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9403         long ident = Binder.clearCallingIdentity();
9404         try {
9405             synchronized (this) {
9406                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9407                 if (task == null) {
9408                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9409                     return;
9410                 }
9411                 int stackId = task.stack.mStackId;
9412                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9413                 // in crop windows resize mode or if the task size is affected by the docked stack
9414                 // changing size. No need to update configuration.
9415                 if (bounds != null && task.inCropWindowsResizeMode()
9416                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9417                     mWindowManager.scrollTask(task.taskId, bounds);
9418                     return;
9419                 }
9420 
9421                 // Place the task in the right stack if it isn't there already based on
9422                 // the requested bounds.
9423                 // The stack transition logic is:
9424                 // - a null bounds on a freeform task moves that task to fullscreen
9425                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9426                 //   that task to freeform
9427                 // - otherwise the task is not moved
9428                 if (!StackId.isTaskResizeAllowed(stackId)) {
9429                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9430                 }
9431                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9432                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9433                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9434                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9435                 }
9436                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9437                 if (stackId != task.stack.mStackId) {
9438                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9439                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9440                     preserveWindow = false;
9441                 }
9442 
9443                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9444                         false /* deferResume */);
9445             }
9446         } finally {
9447             Binder.restoreCallingIdentity(ident);
9448         }
9449     }
9450 
9451     @Override
getTaskBounds(int taskId)9452     public Rect getTaskBounds(int taskId) {
9453         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9454         long ident = Binder.clearCallingIdentity();
9455         Rect rect = new Rect();
9456         try {
9457             synchronized (this) {
9458                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9459                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9460                 if (task == null) {
9461                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9462                     return rect;
9463                 }
9464                 if (task.stack != null) {
9465                     // Return the bounds from window manager since it will be adjusted for various
9466                     // things like the presense of a docked stack for tasks that aren't resizeable.
9467                     mWindowManager.getTaskBounds(task.taskId, rect);
9468                 } else {
9469                     // Task isn't in window manager yet since it isn't associated with a stack.
9470                     // Return the persist value from activity manager
9471                     if (task.mBounds != null) {
9472                         rect.set(task.mBounds);
9473                     } else if (task.mLastNonFullscreenBounds != null) {
9474                         rect.set(task.mLastNonFullscreenBounds);
9475                     }
9476                 }
9477             }
9478         } finally {
9479             Binder.restoreCallingIdentity(ident);
9480         }
9481         return rect;
9482     }
9483 
9484     @Override
getTaskDescriptionIcon(String filePath, int userId)9485     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9486         if (userId != UserHandle.getCallingUserId()) {
9487             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9488                     "getTaskDescriptionIcon");
9489         }
9490         final File passedIconFile = new File(filePath);
9491         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9492                 passedIconFile.getName());
9493         if (!legitIconFile.getPath().equals(filePath)
9494                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9495             throw new IllegalArgumentException("Bad file path: " + filePath
9496                     + " passed for userId " + userId);
9497         }
9498         return mRecentTasks.getTaskDescriptionIcon(filePath);
9499     }
9500 
9501     @Override
startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)9502     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9503             throws RemoteException {
9504         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9505                 opts.getCustomInPlaceResId() == 0) {
9506             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9507                     "with valid animation");
9508         }
9509         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9510         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9511                 opts.getCustomInPlaceResId());
9512         mWindowManager.executeAppTransition();
9513     }
9514 
cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess, boolean removeFromRecents)9515     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9516             boolean removeFromRecents) {
9517         if (removeFromRecents) {
9518             mRecentTasks.remove(tr);
9519             tr.removedFromRecents();
9520         }
9521         ComponentName component = tr.getBaseIntent().getComponent();
9522         if (component == null) {
9523             Slog.w(TAG, "No component for base intent of task: " + tr);
9524             return;
9525         }
9526 
9527         // Find any running services associated with this app and stop if needed.
9528         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9529 
9530         if (!killProcess) {
9531             return;
9532         }
9533 
9534         // Determine if the process(es) for this task should be killed.
9535         final String pkg = component.getPackageName();
9536         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9537         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9538         for (int i = 0; i < pmap.size(); i++) {
9539 
9540             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9541             for (int j = 0; j < uids.size(); j++) {
9542                 ProcessRecord proc = uids.valueAt(j);
9543                 if (proc.userId != tr.userId) {
9544                     // Don't kill process for a different user.
9545                     continue;
9546                 }
9547                 if (proc == mHomeProcess) {
9548                     // Don't kill the home process along with tasks from the same package.
9549                     continue;
9550                 }
9551                 if (!proc.pkgList.containsKey(pkg)) {
9552                     // Don't kill process that is not associated with this task.
9553                     continue;
9554                 }
9555 
9556                 for (int k = 0; k < proc.activities.size(); k++) {
9557                     TaskRecord otherTask = proc.activities.get(k).task;
9558                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9559                         // Don't kill process(es) that has an activity in a different task that is
9560                         // also in recents.
9561                         return;
9562                     }
9563                 }
9564 
9565                 if (proc.foregroundServices) {
9566                     // Don't kill process(es) with foreground service.
9567                     return;
9568                 }
9569 
9570                 // Add process to kill list.
9571                 procsToKill.add(proc);
9572             }
9573         }
9574 
9575         // Kill the running processes.
9576         for (int i = 0; i < procsToKill.size(); i++) {
9577             ProcessRecord pr = procsToKill.get(i);
9578             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9579                     && pr.curReceiver == null) {
9580                 pr.kill("remove task", true);
9581             } else {
9582                 // We delay killing processes that are not in the background or running a receiver.
9583                 pr.waitingToKill = "remove task";
9584             }
9585         }
9586     }
9587 
removeTasksByPackageNameLocked(String packageName, int userId)9588     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9589         // Remove all tasks with activities in the specified package from the list of recent tasks
9590         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9591             TaskRecord tr = mRecentTasks.get(i);
9592             if (tr.userId != userId) continue;
9593 
9594             ComponentName cn = tr.intent.getComponent();
9595             if (cn != null && cn.getPackageName().equals(packageName)) {
9596                 // If the package name matches, remove the task.
9597                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9598             }
9599         }
9600     }
9601 
cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses, int userId)9602     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9603             int userId) {
9604 
9605         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9606             TaskRecord tr = mRecentTasks.get(i);
9607             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9608                 continue;
9609             }
9610 
9611             ComponentName cn = tr.intent.getComponent();
9612             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9613                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9614             if (sameComponent) {
9615                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9616             }
9617         }
9618     }
9619 
9620     /**
9621      * Removes the task with the specified task id.
9622      *
9623      * @param taskId Identifier of the task to be removed.
9624      * @param killProcess Kill any process associated with the task if possible.
9625      * @param removeFromRecents Whether to also remove the task from recents.
9626      * @return Returns true if the given task was found and removed.
9627      */
removeTaskByIdLocked(int taskId, boolean killProcess, boolean removeFromRecents)9628     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9629             boolean removeFromRecents) {
9630         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9631                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9632         if (tr != null) {
9633             tr.removeTaskActivitiesLocked();
9634             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9635             if (tr.isPersistable) {
9636                 notifyTaskPersisterLocked(null, true);
9637             }
9638             return true;
9639         }
9640         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9641         return false;
9642     }
9643 
9644     @Override
removeStack(int stackId)9645     public void removeStack(int stackId) {
9646         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9647         if (stackId == HOME_STACK_ID) {
9648             throw new IllegalArgumentException("Removing home stack is not allowed.");
9649         }
9650 
9651         synchronized (this) {
9652             final long ident = Binder.clearCallingIdentity();
9653             try {
9654                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9655                 if (stack == null) {
9656                     return;
9657                 }
9658                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9659                 for (int i = tasks.size() - 1; i >= 0; i--) {
9660                     removeTaskByIdLocked(
9661                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9662                 }
9663             } finally {
9664                 Binder.restoreCallingIdentity(ident);
9665             }
9666         }
9667     }
9668 
9669     @Override
removeTask(int taskId)9670     public boolean removeTask(int taskId) {
9671         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9672         synchronized (this) {
9673             final long ident = Binder.clearCallingIdentity();
9674             try {
9675                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9676             } finally {
9677                 Binder.restoreCallingIdentity(ident);
9678             }
9679         }
9680     }
9681 
9682     /**
9683      * TODO: Add mController hook
9684      */
9685     @Override
moveTaskToFront(int taskId, int flags, Bundle bOptions)9686     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9687         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9688 
9689         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9690         synchronized(this) {
9691             moveTaskToFrontLocked(taskId, flags, bOptions);
9692         }
9693     }
9694 
moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions)9695     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9696         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9697 
9698         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9699                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9700             ActivityOptions.abort(options);
9701             return;
9702         }
9703         final long origId = Binder.clearCallingIdentity();
9704         try {
9705             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9706             if (task == null) {
9707                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9708                 return;
9709             }
9710             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9711                 mStackSupervisor.showLockTaskToast();
9712                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9713                 return;
9714             }
9715             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9716             if (prev != null && prev.isRecentsActivity()) {
9717                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9718             }
9719             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9720                     false /* forceNonResizable */);
9721         } finally {
9722             Binder.restoreCallingIdentity(origId);
9723         }
9724         ActivityOptions.abort(options);
9725     }
9726 
9727     /**
9728      * Moves an activity, and all of the other activities within the same task, to the bottom
9729      * of the history stack.  The activity's order within the task is unchanged.
9730      *
9731      * @param token A reference to the activity we wish to move
9732      * @param nonRoot If false then this only works if the activity is the root
9733      *                of a task; if true it will work for any activity in a task.
9734      * @return Returns true if the move completed, false if not.
9735      */
9736     @Override
moveActivityTaskToBack(IBinder token, boolean nonRoot)9737     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9738         enforceNotIsolatedCaller("moveActivityTaskToBack");
9739         synchronized(this) {
9740             final long origId = Binder.clearCallingIdentity();
9741             try {
9742                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9743                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9744                 if (task != null) {
9745                     if (mStackSupervisor.isLockedTask(task)) {
9746                         mStackSupervisor.showLockTaskToast();
9747                         return false;
9748                     }
9749                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9750                 }
9751             } finally {
9752                 Binder.restoreCallingIdentity(origId);
9753             }
9754         }
9755         return false;
9756     }
9757 
9758     @Override
moveTaskBackwards(int task)9759     public void moveTaskBackwards(int task) {
9760         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9761                 "moveTaskBackwards()");
9762 
9763         synchronized(this) {
9764             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9765                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9766                 return;
9767             }
9768             final long origId = Binder.clearCallingIdentity();
9769             moveTaskBackwardsLocked(task);
9770             Binder.restoreCallingIdentity(origId);
9771         }
9772     }
9773 
moveTaskBackwardsLocked(int task)9774     private final void moveTaskBackwardsLocked(int task) {
9775         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9776     }
9777 
9778     @Override
createVirtualActivityContainer(IBinder parentActivityToken, IActivityContainerCallback callback)9779     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9780             IActivityContainerCallback callback) throws RemoteException {
9781         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9782         synchronized (this) {
9783             if (parentActivityToken == null) {
9784                 throw new IllegalArgumentException("parent token must not be null");
9785             }
9786             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9787             if (r == null) {
9788                 return null;
9789             }
9790             if (callback == null) {
9791                 throw new IllegalArgumentException("callback must not be null");
9792             }
9793             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9794         }
9795     }
9796 
9797     @Override
deleteActivityContainer(IActivityContainer container)9798     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9799         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9800         synchronized (this) {
9801             mStackSupervisor.deleteActivityContainer(container);
9802         }
9803     }
9804 
9805     @Override
createStackOnDisplay(int displayId)9806     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9807         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9808         synchronized (this) {
9809             final int stackId = mStackSupervisor.getNextStackId();
9810             final ActivityStack stack =
9811                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9812             if (stack == null) {
9813                 return null;
9814             }
9815             return stack.mActivityContainer;
9816         }
9817     }
9818 
9819     @Override
getActivityDisplayId(IBinder activityToken)9820     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9821         synchronized (this) {
9822             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9823             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9824                 return stack.mActivityContainer.getDisplayId();
9825             }
9826             return Display.DEFAULT_DISPLAY;
9827         }
9828     }
9829 
9830     @Override
getActivityStackId(IBinder token)9831     public int getActivityStackId(IBinder token) throws RemoteException {
9832         synchronized (this) {
9833             ActivityStack stack = ActivityRecord.getStackLocked(token);
9834             if (stack == null) {
9835                 return INVALID_STACK_ID;
9836             }
9837             return stack.mStackId;
9838         }
9839     }
9840 
9841     @Override
exitFreeformMode(IBinder token)9842     public void exitFreeformMode(IBinder token) throws RemoteException {
9843         synchronized (this) {
9844             long ident = Binder.clearCallingIdentity();
9845             try {
9846                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9847                 if (r == null) {
9848                     throw new IllegalArgumentException(
9849                             "exitFreeformMode: No activity record matching token=" + token);
9850                 }
9851                 final ActivityStack stack = r.getStackLocked(token);
9852                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9853                     throw new IllegalStateException(
9854                             "exitFreeformMode: You can only go fullscreen from freeform.");
9855                 }
9856                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9857                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9858                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9859             } finally {
9860                 Binder.restoreCallingIdentity(ident);
9861             }
9862         }
9863     }
9864 
9865     @Override
moveTaskToStack(int taskId, int stackId, boolean toTop)9866     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9867         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9868         if (stackId == HOME_STACK_ID) {
9869             throw new IllegalArgumentException(
9870                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9871         }
9872         synchronized (this) {
9873             long ident = Binder.clearCallingIdentity();
9874             try {
9875                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9876                         + " to stackId=" + stackId + " toTop=" + toTop);
9877                 if (stackId == DOCKED_STACK_ID) {
9878                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9879                             null /* initialBounds */);
9880                 }
9881                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9882                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9883                 if (result && stackId == DOCKED_STACK_ID) {
9884                     // If task moved to docked stack - show recents if needed.
9885                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9886                             "moveTaskToDockedStack");
9887                 }
9888             } finally {
9889                 Binder.restoreCallingIdentity(ident);
9890             }
9891         }
9892     }
9893 
9894     @Override
swapDockedAndFullscreenStack()9895     public void swapDockedAndFullscreenStack() throws RemoteException {
9896         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9897         synchronized (this) {
9898             long ident = Binder.clearCallingIdentity();
9899             try {
9900                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9901                         FULLSCREEN_WORKSPACE_STACK_ID);
9902                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9903                         : null;
9904                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9905                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9906                         : null;
9907                 if (topTask == null || tasks == null || tasks.size() == 0) {
9908                     Slog.w(TAG,
9909                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9910                     return;
9911                 }
9912 
9913                 // TODO: App transition
9914                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9915 
9916                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9917                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9918                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9919                         ANIMATE, true /* deferResume */);
9920                 final int size = tasks.size();
9921                 for (int i = 0; i < size; i++) {
9922                     final int id = tasks.get(i).taskId;
9923                     if (id == topTask.taskId) {
9924                         continue;
9925                     }
9926                     mStackSupervisor.moveTaskToStackLocked(id,
9927                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9928                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9929                 }
9930 
9931                 // Because we deferred the resume, to avoid conflicts with stack switches while
9932                 // resuming, we need to do it after all the tasks are moved.
9933                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9934                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9935 
9936                 mWindowManager.executeAppTransition();
9937             } finally {
9938                 Binder.restoreCallingIdentity(ident);
9939             }
9940         }
9941     }
9942 
9943     /**
9944      * Moves the input task to the docked stack.
9945      *
9946      * @param taskId Id of task to move.
9947      * @param createMode The mode the docked stack should be created in if it doesn't exist
9948      *                   already. See
9949      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9950      *                   and
9951      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9952      * @param toTop If the task and stack should be moved to the top.
9953      * @param animate Whether we should play an animation for the moving the task
9954      * @param initialBounds If the docked stack gets created, it will use these bounds for the
9955      *                      docked stack. Pass {@code null} to use default bounds.
9956      */
9957     @Override
moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate, Rect initialBounds, boolean moveHomeStackFront)9958     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9959             Rect initialBounds, boolean moveHomeStackFront) {
9960         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9961         synchronized (this) {
9962             long ident = Binder.clearCallingIdentity();
9963             try {
9964                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9965                         + " to createMode=" + createMode + " toTop=" + toTop);
9966                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
9967                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
9968                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
9969                         animate, DEFER_RESUME);
9970                 if (moved) {
9971                     if (moveHomeStackFront) {
9972                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
9973                     }
9974                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9975                 }
9976                 return moved;
9977             } finally {
9978                 Binder.restoreCallingIdentity(ident);
9979             }
9980         }
9981     }
9982 
9983     /**
9984      * Moves the top activity in the input stackId to the pinned stack.
9985      *
9986      * @param stackId Id of stack to move the top activity to pinned stack.
9987      * @param bounds Bounds to use for pinned stack.
9988      *
9989      * @return True if the top activity of the input stack was successfully moved to the pinned
9990      *          stack.
9991      */
9992     @Override
moveTopActivityToPinnedStack(int stackId, Rect bounds)9993     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
9994         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
9995         synchronized (this) {
9996             if (!mSupportsPictureInPicture) {
9997                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
9998                         + "Device doesn't support picture-in-pciture mode");
9999             }
10000 
10001             long ident = Binder.clearCallingIdentity();
10002             try {
10003                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10004             } finally {
10005                 Binder.restoreCallingIdentity(ident);
10006             }
10007         }
10008     }
10009 
10010     @Override
resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode, boolean preserveWindows, boolean animate, int animationDuration)10011     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10012             boolean preserveWindows, boolean animate, int animationDuration) {
10013         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10014         long ident = Binder.clearCallingIdentity();
10015         try {
10016             synchronized (this) {
10017                 if (animate) {
10018                     if (stackId == PINNED_STACK_ID) {
10019                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10020                     } else {
10021                         throw new IllegalArgumentException("Stack: " + stackId
10022                                 + " doesn't support animated resize.");
10023                     }
10024                 } else {
10025                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10026                             null /* tempTaskInsetBounds */, preserveWindows,
10027                             allowResizeInDockedMode, !DEFER_RESUME);
10028                 }
10029             }
10030         } finally {
10031             Binder.restoreCallingIdentity(ident);
10032         }
10033     }
10034 
10035     @Override
resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds, Rect tempDockedTaskInsetBounds, Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds)10036     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10037             Rect tempDockedTaskInsetBounds,
10038             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10039         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10040                 "resizeDockedStack()");
10041         long ident = Binder.clearCallingIdentity();
10042         try {
10043             synchronized (this) {
10044                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10045                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10046                         PRESERVE_WINDOWS);
10047             }
10048         } finally {
10049             Binder.restoreCallingIdentity(ident);
10050         }
10051     }
10052 
10053     @Override
resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds)10054     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10055         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10056                 "resizePinnedStack()");
10057         final long ident = Binder.clearCallingIdentity();
10058         try {
10059             synchronized (this) {
10060                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10061             }
10062         } finally {
10063             Binder.restoreCallingIdentity(ident);
10064         }
10065     }
10066 
10067     @Override
positionTaskInStack(int taskId, int stackId, int position)10068     public void positionTaskInStack(int taskId, int stackId, int position) {
10069         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10070         if (stackId == HOME_STACK_ID) {
10071             throw new IllegalArgumentException(
10072                     "positionTaskInStack: Attempt to change the position of task "
10073                     + taskId + " in/to home stack");
10074         }
10075         synchronized (this) {
10076             long ident = Binder.clearCallingIdentity();
10077             try {
10078                 if (DEBUG_STACK) Slog.d(TAG_STACK,
10079                         "positionTaskInStack: positioning task=" + taskId
10080                         + " in stackId=" + stackId + " at position=" + position);
10081                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10082             } finally {
10083                 Binder.restoreCallingIdentity(ident);
10084             }
10085         }
10086     }
10087 
10088     @Override
getAllStackInfos()10089     public List<StackInfo> getAllStackInfos() {
10090         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10091         long ident = Binder.clearCallingIdentity();
10092         try {
10093             synchronized (this) {
10094                 return mStackSupervisor.getAllStackInfosLocked();
10095             }
10096         } finally {
10097             Binder.restoreCallingIdentity(ident);
10098         }
10099     }
10100 
10101     @Override
getStackInfo(int stackId)10102     public StackInfo getStackInfo(int stackId) {
10103         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10104         long ident = Binder.clearCallingIdentity();
10105         try {
10106             synchronized (this) {
10107                 return mStackSupervisor.getStackInfoLocked(stackId);
10108             }
10109         } finally {
10110             Binder.restoreCallingIdentity(ident);
10111         }
10112     }
10113 
10114     @Override
isInHomeStack(int taskId)10115     public boolean isInHomeStack(int taskId) {
10116         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10117         long ident = Binder.clearCallingIdentity();
10118         try {
10119             synchronized (this) {
10120                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10121                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10122                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10123             }
10124         } finally {
10125             Binder.restoreCallingIdentity(ident);
10126         }
10127     }
10128 
10129     @Override
getTaskForActivity(IBinder token, boolean onlyRoot)10130     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10131         synchronized(this) {
10132             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10133         }
10134     }
10135 
10136     @Override
updateDeviceOwner(String packageName)10137     public void updateDeviceOwner(String packageName) {
10138         final int callingUid = Binder.getCallingUid();
10139         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10140             throw new SecurityException("updateDeviceOwner called from non-system process");
10141         }
10142         synchronized (this) {
10143             mDeviceOwnerName = packageName;
10144         }
10145     }
10146 
10147     @Override
updateLockTaskPackages(int userId, String[] packages)10148     public void updateLockTaskPackages(int userId, String[] packages) {
10149         final int callingUid = Binder.getCallingUid();
10150         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10151             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10152                     "updateLockTaskPackages()");
10153         }
10154         synchronized (this) {
10155             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10156                     Arrays.toString(packages));
10157             mLockTaskPackages.put(userId, packages);
10158             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10159         }
10160     }
10161 
10162 
startLockTaskModeLocked(TaskRecord task)10163     void startLockTaskModeLocked(TaskRecord task) {
10164         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10165         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10166             return;
10167         }
10168 
10169         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10170         // is initiated by system after the pinning request was shown and locked mode is initiated
10171         // by an authorized app directly
10172         final int callingUid = Binder.getCallingUid();
10173         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10174         long ident = Binder.clearCallingIdentity();
10175         try {
10176             if (!isSystemInitiated) {
10177                 task.mLockTaskUid = callingUid;
10178                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10179                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10180                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10181                     StatusBarManagerInternal statusBarManager =
10182                             LocalServices.getService(StatusBarManagerInternal.class);
10183                     if (statusBarManager != null) {
10184                         statusBarManager.showScreenPinningRequest(task.taskId);
10185                     }
10186                     return;
10187                 }
10188 
10189                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10190                 if (stack == null || task != stack.topTask()) {
10191                     throw new IllegalArgumentException("Invalid task, not in foreground");
10192                 }
10193             }
10194             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10195                     "Locking fully");
10196             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10197                     ActivityManager.LOCK_TASK_MODE_PINNED :
10198                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10199                     "startLockTask", true);
10200         } finally {
10201             Binder.restoreCallingIdentity(ident);
10202         }
10203     }
10204 
10205     @Override
startLockTaskMode(int taskId)10206     public void startLockTaskMode(int taskId) {
10207         synchronized (this) {
10208             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10209             if (task != null) {
10210                 startLockTaskModeLocked(task);
10211             }
10212         }
10213     }
10214 
10215     @Override
startLockTaskMode(IBinder token)10216     public void startLockTaskMode(IBinder token) {
10217         synchronized (this) {
10218             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10219             if (r == null) {
10220                 return;
10221             }
10222             final TaskRecord task = r.task;
10223             if (task != null) {
10224                 startLockTaskModeLocked(task);
10225             }
10226         }
10227     }
10228 
10229     @Override
startSystemLockTaskMode(int taskId)10230     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10231         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10232         // This makes inner call to look as if it was initiated by system.
10233         long ident = Binder.clearCallingIdentity();
10234         try {
10235             synchronized (this) {
10236                 startLockTaskMode(taskId);
10237             }
10238         } finally {
10239             Binder.restoreCallingIdentity(ident);
10240         }
10241     }
10242 
10243     @Override
stopLockTaskMode()10244     public void stopLockTaskMode() {
10245         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10246         if (lockTask == null) {
10247             // Our work here is done.
10248             return;
10249         }
10250 
10251         final int callingUid = Binder.getCallingUid();
10252         final int lockTaskUid = lockTask.mLockTaskUid;
10253         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10254         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10255             // Done.
10256             return;
10257         } else {
10258             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10259             // It is possible lockTaskMode was started by the system process because
10260             // android:lockTaskMode is set to a locking value in the application manifest
10261             // instead of the app calling startLockTaskMode. In this case
10262             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10263             // {@link TaskRecord.effectiveUid} instead. Also caller with
10264             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10265             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10266                     && callingUid != lockTaskUid
10267                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10268                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10269                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10270             }
10271         }
10272         long ident = Binder.clearCallingIdentity();
10273         try {
10274             Log.d(TAG, "stopLockTaskMode");
10275             // Stop lock task
10276             synchronized (this) {
10277                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10278                         "stopLockTask", true);
10279             }
10280             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10281             if (tm != null) {
10282                 tm.showInCallScreen(false);
10283             }
10284         } finally {
10285             Binder.restoreCallingIdentity(ident);
10286         }
10287     }
10288 
10289     /**
10290      * This API should be called by SystemUI only when user perform certain action to dismiss
10291      * lock task mode. We should only dismiss pinned lock task mode in this case.
10292      */
10293     @Override
stopSystemLockTaskMode()10294     public void stopSystemLockTaskMode() throws RemoteException {
10295         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10296             stopLockTaskMode();
10297         } else {
10298             mStackSupervisor.showLockTaskToast();
10299         }
10300     }
10301 
10302     @Override
isInLockTaskMode()10303     public boolean isInLockTaskMode() {
10304         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10305     }
10306 
10307     @Override
getLockTaskModeState()10308     public int getLockTaskModeState() {
10309         synchronized (this) {
10310             return mStackSupervisor.getLockTaskModeState();
10311         }
10312     }
10313 
10314     @Override
showLockTaskEscapeMessage(IBinder token)10315     public void showLockTaskEscapeMessage(IBinder token) {
10316         synchronized (this) {
10317             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10318             if (r == null) {
10319                 return;
10320             }
10321             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10322         }
10323     }
10324 
10325     // =========================================================
10326     // CONTENT PROVIDERS
10327     // =========================================================
10328 
generateApplicationProvidersLocked(ProcessRecord app)10329     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10330         List<ProviderInfo> providers = null;
10331         try {
10332             providers = AppGlobals.getPackageManager()
10333                     .queryContentProviders(app.processName, app.uid,
10334                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10335                                     | MATCH_DEBUG_TRIAGED_MISSING)
10336                     .getList();
10337         } catch (RemoteException ex) {
10338         }
10339         if (DEBUG_MU) Slog.v(TAG_MU,
10340                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10341         int userId = app.userId;
10342         if (providers != null) {
10343             int N = providers.size();
10344             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10345             for (int i=0; i<N; i++) {
10346                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10347                 ProviderInfo cpi =
10348                     (ProviderInfo)providers.get(i);
10349                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10350                         cpi.name, cpi.flags);
10351                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10352                     // This is a singleton provider, but a user besides the
10353                     // default user is asking to initialize a process it runs
10354                     // in...  well, no, it doesn't actually run in this process,
10355                     // it runs in the process of the default user.  Get rid of it.
10356                     providers.remove(i);
10357                     N--;
10358                     i--;
10359                     continue;
10360                 }
10361 
10362                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10363                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10364                 if (cpr == null) {
10365                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10366                     mProviderMap.putProviderByClass(comp, cpr);
10367                 }
10368                 if (DEBUG_MU) Slog.v(TAG_MU,
10369                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10370                 app.pubProviders.put(cpi.name, cpr);
10371                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10372                     // Don't add this if it is a platform component that is marked
10373                     // to run in multiple processes, because this is actually
10374                     // part of the framework so doesn't make sense to track as a
10375                     // separate apk in the process.
10376                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10377                             mProcessStats);
10378                 }
10379                 notifyPackageUse(cpi.applicationInfo.packageName,
10380                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10381             }
10382         }
10383         return providers;
10384     }
10385 
10386     /**
10387      * Check if {@link ProcessRecord} has a possible chance at accessing the
10388      * given {@link ProviderInfo}. Final permission checking is always done
10389      * in {@link ContentProvider}.
10390      */
checkContentProviderPermissionLocked( ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser)10391     private final String checkContentProviderPermissionLocked(
10392             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10393         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10394         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10395         boolean checkedGrants = false;
10396         if (checkUser) {
10397             // Looking for cross-user grants before enforcing the typical cross-users permissions
10398             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10399             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10400                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10401                     return null;
10402                 }
10403                 checkedGrants = true;
10404             }
10405             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10406                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10407             if (userId != tmpTargetUserId) {
10408                 // When we actually went to determine the final targer user ID, this ended
10409                 // up different than our initial check for the authority.  This is because
10410                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10411                 // SELF.  So we need to re-check the grants again.
10412                 checkedGrants = false;
10413             }
10414         }
10415         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10416                 cpi.applicationInfo.uid, cpi.exported)
10417                 == PackageManager.PERMISSION_GRANTED) {
10418             return null;
10419         }
10420         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10421                 cpi.applicationInfo.uid, cpi.exported)
10422                 == PackageManager.PERMISSION_GRANTED) {
10423             return null;
10424         }
10425 
10426         PathPermission[] pps = cpi.pathPermissions;
10427         if (pps != null) {
10428             int i = pps.length;
10429             while (i > 0) {
10430                 i--;
10431                 PathPermission pp = pps[i];
10432                 String pprperm = pp.getReadPermission();
10433                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10434                         cpi.applicationInfo.uid, cpi.exported)
10435                         == PackageManager.PERMISSION_GRANTED) {
10436                     return null;
10437                 }
10438                 String ppwperm = pp.getWritePermission();
10439                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10440                         cpi.applicationInfo.uid, cpi.exported)
10441                         == PackageManager.PERMISSION_GRANTED) {
10442                     return null;
10443                 }
10444             }
10445         }
10446         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10447             return null;
10448         }
10449 
10450         String msg;
10451         if (!cpi.exported) {
10452             msg = "Permission Denial: opening provider " + cpi.name
10453                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10454                     + ", uid=" + callingUid + ") that is not exported from uid "
10455                     + cpi.applicationInfo.uid;
10456         } else {
10457             msg = "Permission Denial: opening provider " + cpi.name
10458                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10459                     + ", uid=" + callingUid + ") requires "
10460                     + cpi.readPermission + " or " + cpi.writePermission;
10461         }
10462         Slog.w(TAG, msg);
10463         return msg;
10464     }
10465 
10466     /**
10467      * Returns if the ContentProvider has granted a uri to callingUid
10468      */
checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser)10469     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10470         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10471         if (perms != null) {
10472             for (int i=perms.size()-1; i>=0; i--) {
10473                 GrantUri grantUri = perms.keyAt(i);
10474                 if (grantUri.sourceUserId == userId || !checkUser) {
10475                     if (matchesProvider(grantUri.uri, cpi)) {
10476                         return true;
10477                     }
10478                 }
10479             }
10480         }
10481         return false;
10482     }
10483 
10484     /**
10485      * Returns true if the uri authority is one of the authorities specified in the provider.
10486      */
matchesProvider(Uri uri, ProviderInfo cpi)10487     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10488         String uriAuth = uri.getAuthority();
10489         String cpiAuth = cpi.authority;
10490         if (cpiAuth.indexOf(';') == -1) {
10491             return cpiAuth.equals(uriAuth);
10492         }
10493         String[] cpiAuths = cpiAuth.split(";");
10494         int length = cpiAuths.length;
10495         for (int i = 0; i < length; i++) {
10496             if (cpiAuths[i].equals(uriAuth)) return true;
10497         }
10498         return false;
10499     }
10500 
incProviderCountLocked(ProcessRecord r, final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable)10501     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10502             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10503         if (r != null) {
10504             for (int i=0; i<r.conProviders.size(); i++) {
10505                 ContentProviderConnection conn = r.conProviders.get(i);
10506                 if (conn.provider == cpr) {
10507                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10508                             "Adding provider requested by "
10509                             + r.processName + " from process "
10510                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10511                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10512                     if (stable) {
10513                         conn.stableCount++;
10514                         conn.numStableIncs++;
10515                     } else {
10516                         conn.unstableCount++;
10517                         conn.numUnstableIncs++;
10518                     }
10519                     return conn;
10520                 }
10521             }
10522             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10523             if (stable) {
10524                 conn.stableCount = 1;
10525                 conn.numStableIncs = 1;
10526             } else {
10527                 conn.unstableCount = 1;
10528                 conn.numUnstableIncs = 1;
10529             }
10530             cpr.connections.add(conn);
10531             r.conProviders.add(conn);
10532             startAssociationLocked(r.uid, r.processName, r.curProcState,
10533                     cpr.uid, cpr.name, cpr.info.processName);
10534             return conn;
10535         }
10536         cpr.addExternalProcessHandleLocked(externalProcessToken);
10537         return null;
10538     }
10539 
decProviderCountLocked(ContentProviderConnection conn, ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable)10540     boolean decProviderCountLocked(ContentProviderConnection conn,
10541             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10542         if (conn != null) {
10543             cpr = conn.provider;
10544             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10545                     "Removing provider requested by "
10546                     + conn.client.processName + " from process "
10547                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10548                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10549             if (stable) {
10550                 conn.stableCount--;
10551             } else {
10552                 conn.unstableCount--;
10553             }
10554             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10555                 cpr.connections.remove(conn);
10556                 conn.client.conProviders.remove(conn);
10557                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10558                     // The client is more important than last activity -- note the time this
10559                     // is happening, so we keep the old provider process around a bit as last
10560                     // activity to avoid thrashing it.
10561                     if (cpr.proc != null) {
10562                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10563                     }
10564                 }
10565                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10566                 return true;
10567             }
10568             return false;
10569         }
10570         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10571         return false;
10572     }
10573 
checkTime(long startTime, String where)10574     private void checkTime(long startTime, String where) {
10575         long now = SystemClock.uptimeMillis();
10576         if ((now-startTime) > 50) {
10577             // If we are taking more than 50ms, log about it.
10578             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10579         }
10580     }
10581 
10582     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10583             PROC_SPACE_TERM,
10584             PROC_SPACE_TERM|PROC_PARENS,
10585             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10586     };
10587 
10588     private final long[] mProcessStateStatsLongs = new long[1];
10589 
isProcessAliveLocked(ProcessRecord proc)10590     boolean isProcessAliveLocked(ProcessRecord proc) {
10591         if (proc.procStatFile == null) {
10592             proc.procStatFile = "/proc/" + proc.pid + "/stat";
10593         }
10594         mProcessStateStatsLongs[0] = 0;
10595         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10596                 mProcessStateStatsLongs, null)) {
10597             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10598             return false;
10599         }
10600         final long state = mProcessStateStatsLongs[0];
10601         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10602                 + (char)state);
10603         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10604     }
10605 
getContentProviderImpl(IApplicationThread caller, String name, IBinder token, boolean stable, int userId)10606     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10607             String name, IBinder token, boolean stable, int userId) {
10608         ContentProviderRecord cpr;
10609         ContentProviderConnection conn = null;
10610         ProviderInfo cpi = null;
10611 
10612         synchronized(this) {
10613             long startTime = SystemClock.uptimeMillis();
10614 
10615             ProcessRecord r = null;
10616             if (caller != null) {
10617                 r = getRecordForAppLocked(caller);
10618                 if (r == null) {
10619                     throw new SecurityException(
10620                             "Unable to find app for caller " + caller
10621                           + " (pid=" + Binder.getCallingPid()
10622                           + ") when getting content provider " + name);
10623                 }
10624             }
10625 
10626             boolean checkCrossUser = true;
10627 
10628             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10629 
10630             // First check if this content provider has been published...
10631             cpr = mProviderMap.getProviderByName(name, userId);
10632             // If that didn't work, check if it exists for user 0 and then
10633             // verify that it's a singleton provider before using it.
10634             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10635                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10636                 if (cpr != null) {
10637                     cpi = cpr.info;
10638                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10639                             cpi.name, cpi.flags)
10640                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10641                         userId = UserHandle.USER_SYSTEM;
10642                         checkCrossUser = false;
10643                     } else {
10644                         cpr = null;
10645                         cpi = null;
10646                     }
10647                 }
10648             }
10649 
10650             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10651             if (providerRunning) {
10652                 cpi = cpr.info;
10653                 String msg;
10654                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10655                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10656                         != null) {
10657                     throw new SecurityException(msg);
10658                 }
10659                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10660 
10661                 if (r != null && cpr.canRunHere(r)) {
10662                     // This provider has been published or is in the process
10663                     // of being published...  but it is also allowed to run
10664                     // in the caller's process, so don't make a connection
10665                     // and just let the caller instantiate its own instance.
10666                     ContentProviderHolder holder = cpr.newHolder(null);
10667                     // don't give caller the provider object, it needs
10668                     // to make its own.
10669                     holder.provider = null;
10670                     return holder;
10671                 }
10672 
10673                 final long origId = Binder.clearCallingIdentity();
10674 
10675                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10676 
10677                 // In this case the provider instance already exists, so we can
10678                 // return it right away.
10679                 conn = incProviderCountLocked(r, cpr, token, stable);
10680                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10681                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10682                         // If this is a perceptible app accessing the provider,
10683                         // make sure to count it as being accessed and thus
10684                         // back up on the LRU list.  This is good because
10685                         // content providers are often expensive to start.
10686                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10687                         updateLruProcessLocked(cpr.proc, false, null);
10688                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10689                     }
10690                 }
10691 
10692                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10693                 final int verifiedAdj = cpr.proc.verifiedAdj;
10694                 boolean success = updateOomAdjLocked(cpr.proc);
10695                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10696                 // if the process has been successfully adjusted.  So to reduce races with
10697                 // it, we will check whether the process still exists.  Note that this doesn't
10698                 // completely get rid of races with LMK killing the process, but should make
10699                 // them much smaller.
10700                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10701                     success = false;
10702                 }
10703                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10704                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10705                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10706                 // NOTE: there is still a race here where a signal could be
10707                 // pending on the process even though we managed to update its
10708                 // adj level.  Not sure what to do about this, but at least
10709                 // the race is now smaller.
10710                 if (!success) {
10711                     // Uh oh...  it looks like the provider's process
10712                     // has been killed on us.  We need to wait for a new
10713                     // process to be started, and make sure its death
10714                     // doesn't kill our process.
10715                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10716                             + " is crashing; detaching " + r);
10717                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10718                     checkTime(startTime, "getContentProviderImpl: before appDied");
10719                     appDiedLocked(cpr.proc);
10720                     checkTime(startTime, "getContentProviderImpl: after appDied");
10721                     if (!lastRef) {
10722                         // This wasn't the last ref our process had on
10723                         // the provider...  we have now been killed, bail.
10724                         return null;
10725                     }
10726                     providerRunning = false;
10727                     conn = null;
10728                 } else {
10729                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
10730                 }
10731 
10732                 Binder.restoreCallingIdentity(origId);
10733             }
10734 
10735             if (!providerRunning) {
10736                 try {
10737                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10738                     cpi = AppGlobals.getPackageManager().
10739                         resolveContentProvider(name,
10740                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10741                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10742                 } catch (RemoteException ex) {
10743                 }
10744                 if (cpi == null) {
10745                     return null;
10746                 }
10747                 // If the provider is a singleton AND
10748                 // (it's a call within the same user || the provider is a
10749                 // privileged app)
10750                 // Then allow connecting to the singleton provider
10751                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10752                         cpi.name, cpi.flags)
10753                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10754                 if (singleton) {
10755                     userId = UserHandle.USER_SYSTEM;
10756                 }
10757                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10758                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10759 
10760                 String msg;
10761                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10762                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10763                         != null) {
10764                     throw new SecurityException(msg);
10765                 }
10766                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10767 
10768                 if (!mProcessesReady
10769                         && !cpi.processName.equals("system")) {
10770                     // If this content provider does not run in the system
10771                     // process, and the system is not yet ready to run other
10772                     // processes, then fail fast instead of hanging.
10773                     throw new IllegalArgumentException(
10774                             "Attempt to launch content provider before system ready");
10775                 }
10776 
10777                 // Make sure that the user who owns this provider is running.  If not,
10778                 // we don't want to allow it to run.
10779                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10780                     Slog.w(TAG, "Unable to launch app "
10781                             + cpi.applicationInfo.packageName + "/"
10782                             + cpi.applicationInfo.uid + " for provider "
10783                             + name + ": user " + userId + " is stopped");
10784                     return null;
10785                 }
10786 
10787                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10788                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10789                 cpr = mProviderMap.getProviderByClass(comp, userId);
10790                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10791                 final boolean firstClass = cpr == null;
10792                 if (firstClass) {
10793                     final long ident = Binder.clearCallingIdentity();
10794 
10795                     // If permissions need a review before any of the app components can run,
10796                     // we return no provider and launch a review activity if the calling app
10797                     // is in the foreground.
10798                     if (Build.PERMISSIONS_REVIEW_REQUIRED) {
10799                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10800                             return null;
10801                         }
10802                     }
10803 
10804                     try {
10805                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10806                         ApplicationInfo ai =
10807                             AppGlobals.getPackageManager().
10808                                 getApplicationInfo(
10809                                         cpi.applicationInfo.packageName,
10810                                         STOCK_PM_FLAGS, userId);
10811                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10812                         if (ai == null) {
10813                             Slog.w(TAG, "No package info for content provider "
10814                                     + cpi.name);
10815                             return null;
10816                         }
10817                         ai = getAppInfoForUser(ai, userId);
10818                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10819                     } catch (RemoteException ex) {
10820                         // pm is in same process, this will never happen.
10821                     } finally {
10822                         Binder.restoreCallingIdentity(ident);
10823                     }
10824                 }
10825 
10826                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10827 
10828                 if (r != null && cpr.canRunHere(r)) {
10829                     // If this is a multiprocess provider, then just return its
10830                     // info and allow the caller to instantiate it.  Only do
10831                     // this if the provider is the same user as the caller's
10832                     // process, or can run as root (so can be in any process).
10833                     return cpr.newHolder(null);
10834                 }
10835 
10836                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10837                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10838                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10839 
10840                 // This is single process, and our app is now connecting to it.
10841                 // See if we are already in the process of launching this
10842                 // provider.
10843                 final int N = mLaunchingProviders.size();
10844                 int i;
10845                 for (i = 0; i < N; i++) {
10846                     if (mLaunchingProviders.get(i) == cpr) {
10847                         break;
10848                     }
10849                 }
10850 
10851                 // If the provider is not already being launched, then get it
10852                 // started.
10853                 if (i >= N) {
10854                     final long origId = Binder.clearCallingIdentity();
10855 
10856                     try {
10857                         // Content provider is now in use, its package can't be stopped.
10858                         try {
10859                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10860                             AppGlobals.getPackageManager().setPackageStoppedState(
10861                                     cpr.appInfo.packageName, false, userId);
10862                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10863                         } catch (RemoteException e) {
10864                         } catch (IllegalArgumentException e) {
10865                             Slog.w(TAG, "Failed trying to unstop package "
10866                                     + cpr.appInfo.packageName + ": " + e);
10867                         }
10868 
10869                         // Use existing process if already started
10870                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10871                         ProcessRecord proc = getProcessRecordLocked(
10872                                 cpi.processName, cpr.appInfo.uid, false);
10873                         if (proc != null && proc.thread != null && !proc.killed) {
10874                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10875                                     "Installing in existing process " + proc);
10876                             if (!proc.pubProviders.containsKey(cpi.name)) {
10877                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10878                                 proc.pubProviders.put(cpi.name, cpr);
10879                                 try {
10880                                     proc.thread.scheduleInstallProvider(cpi);
10881                                 } catch (RemoteException e) {
10882                                 }
10883                             }
10884                         } else {
10885                             checkTime(startTime, "getContentProviderImpl: before start process");
10886                             proc = startProcessLocked(cpi.processName,
10887                                     cpr.appInfo, false, 0, "content provider",
10888                                     new ComponentName(cpi.applicationInfo.packageName,
10889                                             cpi.name), false, false, false);
10890                             checkTime(startTime, "getContentProviderImpl: after start process");
10891                             if (proc == null) {
10892                                 Slog.w(TAG, "Unable to launch app "
10893                                         + cpi.applicationInfo.packageName + "/"
10894                                         + cpi.applicationInfo.uid + " for provider "
10895                                         + name + ": process is bad");
10896                                 return null;
10897                             }
10898                         }
10899                         cpr.launchingApp = proc;
10900                         mLaunchingProviders.add(cpr);
10901                     } finally {
10902                         Binder.restoreCallingIdentity(origId);
10903                     }
10904                 }
10905 
10906                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10907 
10908                 // Make sure the provider is published (the same provider class
10909                 // may be published under multiple names).
10910                 if (firstClass) {
10911                     mProviderMap.putProviderByClass(comp, cpr);
10912                 }
10913 
10914                 mProviderMap.putProviderByName(name, cpr);
10915                 conn = incProviderCountLocked(r, cpr, token, stable);
10916                 if (conn != null) {
10917                     conn.waiting = true;
10918                 }
10919             }
10920             checkTime(startTime, "getContentProviderImpl: done!");
10921         }
10922 
10923         // Wait for the provider to be published...
10924         synchronized (cpr) {
10925             while (cpr.provider == null) {
10926                 if (cpr.launchingApp == null) {
10927                     Slog.w(TAG, "Unable to launch app "
10928                             + cpi.applicationInfo.packageName + "/"
10929                             + cpi.applicationInfo.uid + " for provider "
10930                             + name + ": launching app became null");
10931                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
10932                             UserHandle.getUserId(cpi.applicationInfo.uid),
10933                             cpi.applicationInfo.packageName,
10934                             cpi.applicationInfo.uid, name);
10935                     return null;
10936                 }
10937                 try {
10938                     if (DEBUG_MU) Slog.v(TAG_MU,
10939                             "Waiting to start provider " + cpr
10940                             + " launchingApp=" + cpr.launchingApp);
10941                     if (conn != null) {
10942                         conn.waiting = true;
10943                     }
10944                     cpr.wait();
10945                 } catch (InterruptedException ex) {
10946                 } finally {
10947                     if (conn != null) {
10948                         conn.waiting = false;
10949                     }
10950                 }
10951             }
10952         }
10953         return cpr != null ? cpr.newHolder(conn) : null;
10954     }
10955 
requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi, ProcessRecord r, final int userId)10956     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
10957             ProcessRecord r, final int userId) {
10958         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
10959                 cpi.packageName, userId)) {
10960 
10961             final boolean callerForeground = r == null || r.setSchedGroup
10962                     != ProcessList.SCHED_GROUP_BACKGROUND;
10963 
10964             // Show a permission review UI only for starting from a foreground app
10965             if (!callerForeground) {
10966                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
10967                         + cpi.packageName + " requires a permissions review");
10968                 return false;
10969             }
10970 
10971             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
10972             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
10973                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
10974             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
10975 
10976             if (DEBUG_PERMISSIONS_REVIEW) {
10977                 Slog.i(TAG, "u" + userId + " Launching permission review "
10978                         + "for package " + cpi.packageName);
10979             }
10980 
10981             final UserHandle userHandle = new UserHandle(userId);
10982             mHandler.post(new Runnable() {
10983                 @Override
10984                 public void run() {
10985                     mContext.startActivityAsUser(intent, userHandle);
10986                 }
10987             });
10988 
10989             return false;
10990         }
10991 
10992         return true;
10993     }
10994 
getPackageManagerInternalLocked()10995     PackageManagerInternal getPackageManagerInternalLocked() {
10996         if (mPackageManagerInt == null) {
10997             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
10998         }
10999         return mPackageManagerInt;
11000     }
11001 
11002     @Override
getContentProvider( IApplicationThread caller, String name, int userId, boolean stable)11003     public final ContentProviderHolder getContentProvider(
11004             IApplicationThread caller, String name, int userId, boolean stable) {
11005         enforceNotIsolatedCaller("getContentProvider");
11006         if (caller == null) {
11007             String msg = "null IApplicationThread when getting content provider "
11008                     + name;
11009             Slog.w(TAG, msg);
11010             throw new SecurityException(msg);
11011         }
11012         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11013         // with cross-user grant.
11014         return getContentProviderImpl(caller, name, null, stable, userId);
11015     }
11016 
getContentProviderExternal( String name, int userId, IBinder token)11017     public ContentProviderHolder getContentProviderExternal(
11018             String name, int userId, IBinder token) {
11019         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11020             "Do not have permission in call getContentProviderExternal()");
11021         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11022                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11023         return getContentProviderExternalUnchecked(name, token, userId);
11024     }
11025 
getContentProviderExternalUnchecked(String name, IBinder token, int userId)11026     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11027             IBinder token, int userId) {
11028         return getContentProviderImpl(null, name, token, true, userId);
11029     }
11030 
11031     /**
11032      * Drop a content provider from a ProcessRecord's bookkeeping
11033      */
removeContentProvider(IBinder connection, boolean stable)11034     public void removeContentProvider(IBinder connection, boolean stable) {
11035         enforceNotIsolatedCaller("removeContentProvider");
11036         long ident = Binder.clearCallingIdentity();
11037         try {
11038             synchronized (this) {
11039                 ContentProviderConnection conn;
11040                 try {
11041                     conn = (ContentProviderConnection)connection;
11042                 } catch (ClassCastException e) {
11043                     String msg ="removeContentProvider: " + connection
11044                             + " not a ContentProviderConnection";
11045                     Slog.w(TAG, msg);
11046                     throw new IllegalArgumentException(msg);
11047                 }
11048                 if (conn == null) {
11049                     throw new NullPointerException("connection is null");
11050                 }
11051                 if (decProviderCountLocked(conn, null, null, stable)) {
11052                     updateOomAdjLocked();
11053                 }
11054             }
11055         } finally {
11056             Binder.restoreCallingIdentity(ident);
11057         }
11058     }
11059 
removeContentProviderExternal(String name, IBinder token)11060     public void removeContentProviderExternal(String name, IBinder token) {
11061         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11062             "Do not have permission in call removeContentProviderExternal()");
11063         int userId = UserHandle.getCallingUserId();
11064         long ident = Binder.clearCallingIdentity();
11065         try {
11066             removeContentProviderExternalUnchecked(name, token, userId);
11067         } finally {
11068             Binder.restoreCallingIdentity(ident);
11069         }
11070     }
11071 
removeContentProviderExternalUnchecked(String name, IBinder token, int userId)11072     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11073         synchronized (this) {
11074             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11075             if(cpr == null) {
11076                 //remove from mProvidersByClass
11077                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11078                 return;
11079             }
11080 
11081             //update content provider record entry info
11082             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11083             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11084             if (localCpr.hasExternalProcessHandles()) {
11085                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11086                     updateOomAdjLocked();
11087                 } else {
11088                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11089                             + " with no external reference for token: "
11090                             + token + ".");
11091                 }
11092             } else {
11093                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11094                         + " with no external references.");
11095             }
11096         }
11097     }
11098 
publishContentProviders(IApplicationThread caller, List<ContentProviderHolder> providers)11099     public final void publishContentProviders(IApplicationThread caller,
11100             List<ContentProviderHolder> providers) {
11101         if (providers == null) {
11102             return;
11103         }
11104 
11105         enforceNotIsolatedCaller("publishContentProviders");
11106         synchronized (this) {
11107             final ProcessRecord r = getRecordForAppLocked(caller);
11108             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11109             if (r == null) {
11110                 throw new SecurityException(
11111                         "Unable to find app for caller " + caller
11112                       + " (pid=" + Binder.getCallingPid()
11113                       + ") when publishing content providers");
11114             }
11115 
11116             final long origId = Binder.clearCallingIdentity();
11117 
11118             final int N = providers.size();
11119             for (int i = 0; i < N; i++) {
11120                 ContentProviderHolder src = providers.get(i);
11121                 if (src == null || src.info == null || src.provider == null) {
11122                     continue;
11123                 }
11124                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11125                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11126                 if (dst != null) {
11127                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11128                     mProviderMap.putProviderByClass(comp, dst);
11129                     String names[] = dst.info.authority.split(";");
11130                     for (int j = 0; j < names.length; j++) {
11131                         mProviderMap.putProviderByName(names[j], dst);
11132                     }
11133 
11134                     int launchingCount = mLaunchingProviders.size();
11135                     int j;
11136                     boolean wasInLaunchingProviders = false;
11137                     for (j = 0; j < launchingCount; j++) {
11138                         if (mLaunchingProviders.get(j) == dst) {
11139                             mLaunchingProviders.remove(j);
11140                             wasInLaunchingProviders = true;
11141                             j--;
11142                             launchingCount--;
11143                         }
11144                     }
11145                     if (wasInLaunchingProviders) {
11146                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11147                     }
11148                     synchronized (dst) {
11149                         dst.provider = src.provider;
11150                         dst.proc = r;
11151                         dst.notifyAll();
11152                     }
11153                     updateOomAdjLocked(r);
11154                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11155                             src.info.authority);
11156                 }
11157             }
11158 
11159             Binder.restoreCallingIdentity(origId);
11160         }
11161     }
11162 
refContentProvider(IBinder connection, int stable, int unstable)11163     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11164         ContentProviderConnection conn;
11165         try {
11166             conn = (ContentProviderConnection)connection;
11167         } catch (ClassCastException e) {
11168             String msg ="refContentProvider: " + connection
11169                     + " not a ContentProviderConnection";
11170             Slog.w(TAG, msg);
11171             throw new IllegalArgumentException(msg);
11172         }
11173         if (conn == null) {
11174             throw new NullPointerException("connection is null");
11175         }
11176 
11177         synchronized (this) {
11178             if (stable > 0) {
11179                 conn.numStableIncs += stable;
11180             }
11181             stable = conn.stableCount + stable;
11182             if (stable < 0) {
11183                 throw new IllegalStateException("stableCount < 0: " + stable);
11184             }
11185 
11186             if (unstable > 0) {
11187                 conn.numUnstableIncs += unstable;
11188             }
11189             unstable = conn.unstableCount + unstable;
11190             if (unstable < 0) {
11191                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11192             }
11193 
11194             if ((stable+unstable) <= 0) {
11195                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11196                         + stable + " unstable=" + unstable);
11197             }
11198             conn.stableCount = stable;
11199             conn.unstableCount = unstable;
11200             return !conn.dead;
11201         }
11202     }
11203 
unstableProviderDied(IBinder connection)11204     public void unstableProviderDied(IBinder connection) {
11205         ContentProviderConnection conn;
11206         try {
11207             conn = (ContentProviderConnection)connection;
11208         } catch (ClassCastException e) {
11209             String msg ="refContentProvider: " + connection
11210                     + " not a ContentProviderConnection";
11211             Slog.w(TAG, msg);
11212             throw new IllegalArgumentException(msg);
11213         }
11214         if (conn == null) {
11215             throw new NullPointerException("connection is null");
11216         }
11217 
11218         // Safely retrieve the content provider associated with the connection.
11219         IContentProvider provider;
11220         synchronized (this) {
11221             provider = conn.provider.provider;
11222         }
11223 
11224         if (provider == null) {
11225             // Um, yeah, we're way ahead of you.
11226             return;
11227         }
11228 
11229         // Make sure the caller is being honest with us.
11230         if (provider.asBinder().pingBinder()) {
11231             // Er, no, still looks good to us.
11232             synchronized (this) {
11233                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11234                         + " says " + conn + " died, but we don't agree");
11235                 return;
11236             }
11237         }
11238 
11239         // Well look at that!  It's dead!
11240         synchronized (this) {
11241             if (conn.provider.provider != provider) {
11242                 // But something changed...  good enough.
11243                 return;
11244             }
11245 
11246             ProcessRecord proc = conn.provider.proc;
11247             if (proc == null || proc.thread == null) {
11248                 // Seems like the process is already cleaned up.
11249                 return;
11250             }
11251 
11252             // As far as we're concerned, this is just like receiving a
11253             // death notification...  just a bit prematurely.
11254             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11255                     + ") early provider death");
11256             final long ident = Binder.clearCallingIdentity();
11257             try {
11258                 appDiedLocked(proc);
11259             } finally {
11260                 Binder.restoreCallingIdentity(ident);
11261             }
11262         }
11263     }
11264 
11265     @Override
appNotRespondingViaProvider(IBinder connection)11266     public void appNotRespondingViaProvider(IBinder connection) {
11267         enforceCallingPermission(
11268                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11269 
11270         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11271         if (conn == null) {
11272             Slog.w(TAG, "ContentProviderConnection is null");
11273             return;
11274         }
11275 
11276         final ProcessRecord host = conn.provider.proc;
11277         if (host == null) {
11278             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11279             return;
11280         }
11281 
11282         mHandler.post(new Runnable() {
11283             @Override
11284             public void run() {
11285                 mAppErrors.appNotResponding(host, null, null, false,
11286                         "ContentProvider not responding");
11287             }
11288         });
11289     }
11290 
installSystemProviders()11291     public final void installSystemProviders() {
11292         List<ProviderInfo> providers;
11293         synchronized (this) {
11294             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11295             providers = generateApplicationProvidersLocked(app);
11296             if (providers != null) {
11297                 for (int i=providers.size()-1; i>=0; i--) {
11298                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11299                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11300                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11301                                 + ": not system .apk");
11302                         providers.remove(i);
11303                     }
11304                 }
11305             }
11306         }
11307         if (providers != null) {
11308             mSystemThread.installSystemProviders(providers);
11309         }
11310 
11311         mCoreSettingsObserver = new CoreSettingsObserver(this);
11312         mFontScaleSettingObserver = new FontScaleSettingObserver();
11313 
11314         //mUsageStatsService.monitorPackages();
11315     }
11316 
startPersistentApps(int matchFlags)11317     private void startPersistentApps(int matchFlags) {
11318         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11319 
11320         synchronized (this) {
11321             try {
11322                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11323                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11324                 for (ApplicationInfo app : apps) {
11325                     if (!"android".equals(app.packageName)) {
11326                         addAppLocked(app, false, null /* ABI override */);
11327                     }
11328                 }
11329             } catch (RemoteException ex) {
11330             }
11331         }
11332     }
11333 
11334     /**
11335      * When a user is unlocked, we need to install encryption-unaware providers
11336      * belonging to any running apps.
11337      */
installEncryptionUnawareProviders(int userId)11338     private void installEncryptionUnawareProviders(int userId) {
11339         // We're only interested in providers that are encryption unaware, and
11340         // we don't care about uninstalled apps, since there's no way they're
11341         // running at this point.
11342         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11343 
11344         synchronized (this) {
11345             final int NP = mProcessNames.getMap().size();
11346             for (int ip = 0; ip < NP; ip++) {
11347                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11348                 final int NA = apps.size();
11349                 for (int ia = 0; ia < NA; ia++) {
11350                     final ProcessRecord app = apps.valueAt(ia);
11351                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
11352 
11353                     final int NG = app.pkgList.size();
11354                     for (int ig = 0; ig < NG; ig++) {
11355                         try {
11356                             final String pkgName = app.pkgList.keyAt(ig);
11357                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11358                                     .getPackageInfo(pkgName, matchFlags, userId);
11359                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11360                                 for (ProviderInfo pi : pkgInfo.providers) {
11361                                     // TODO: keep in sync with generateApplicationProvidersLocked
11362                                     final boolean processMatch = Objects.equals(pi.processName,
11363                                             app.processName) || pi.multiprocess;
11364                                     final boolean userMatch = isSingleton(pi.processName,
11365                                             pi.applicationInfo, pi.name, pi.flags)
11366                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
11367                                     if (processMatch && userMatch) {
11368                                         Log.v(TAG, "Installing " + pi);
11369                                         app.thread.scheduleInstallProvider(pi);
11370                                     } else {
11371                                         Log.v(TAG, "Skipping " + pi);
11372                                     }
11373                                 }
11374                             }
11375                         } catch (RemoteException ignored) {
11376                         }
11377                     }
11378                 }
11379             }
11380         }
11381     }
11382 
11383     /**
11384      * Allows apps to retrieve the MIME type of a URI.
11385      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11386      * users, then it does not need permission to access the ContentProvider.
11387      * Either, it needs cross-user uri grants.
11388      *
11389      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11390      *
11391      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11392      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11393      */
getProviderMimeType(Uri uri, int userId)11394     public String getProviderMimeType(Uri uri, int userId) {
11395         enforceNotIsolatedCaller("getProviderMimeType");
11396         final String name = uri.getAuthority();
11397         int callingUid = Binder.getCallingUid();
11398         int callingPid = Binder.getCallingPid();
11399         long ident = 0;
11400         boolean clearedIdentity = false;
11401         synchronized (this) {
11402             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11403         }
11404         if (canClearIdentity(callingPid, callingUid, userId)) {
11405             clearedIdentity = true;
11406             ident = Binder.clearCallingIdentity();
11407         }
11408         ContentProviderHolder holder = null;
11409         try {
11410             holder = getContentProviderExternalUnchecked(name, null, userId);
11411             if (holder != null) {
11412                 return holder.provider.getType(uri);
11413             }
11414         } catch (RemoteException e) {
11415             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11416             return null;
11417         } catch (Exception e) {
11418             Log.w(TAG, "Exception while determining type of " + uri, e);
11419             return null;
11420         } finally {
11421             // We need to clear the identity to call removeContentProviderExternalUnchecked
11422             if (!clearedIdentity) {
11423                 ident = Binder.clearCallingIdentity();
11424             }
11425             try {
11426                 if (holder != null) {
11427                     removeContentProviderExternalUnchecked(name, null, userId);
11428                 }
11429             } finally {
11430                 Binder.restoreCallingIdentity(ident);
11431             }
11432         }
11433 
11434         return null;
11435     }
11436 
canClearIdentity(int callingPid, int callingUid, int userId)11437     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11438         if (UserHandle.getUserId(callingUid) == userId) {
11439             return true;
11440         }
11441         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11442                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11443                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11444                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11445                 return true;
11446         }
11447         return false;
11448     }
11449 
11450     // =========================================================
11451     // GLOBAL MANAGEMENT
11452     // =========================================================
11453 
newProcessRecordLocked(ApplicationInfo info, String customProcess, boolean isolated, int isolatedUid)11454     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11455             boolean isolated, int isolatedUid) {
11456         String proc = customProcess != null ? customProcess : info.processName;
11457         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11458         final int userId = UserHandle.getUserId(info.uid);
11459         int uid = info.uid;
11460         if (isolated) {
11461             if (isolatedUid == 0) {
11462                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11463                 while (true) {
11464                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11465                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11466                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11467                     }
11468                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11469                     mNextIsolatedProcessUid++;
11470                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11471                         // No process for this uid, use it.
11472                         break;
11473                     }
11474                     stepsLeft--;
11475                     if (stepsLeft <= 0) {
11476                         return null;
11477                     }
11478                 }
11479             } else {
11480                 // Special case for startIsolatedProcess (internal only), where
11481                 // the uid of the isolated process is specified by the caller.
11482                 uid = isolatedUid;
11483             }
11484 
11485             // Register the isolated UID with this application so BatteryStats knows to
11486             // attribute resource usage to the application.
11487             //
11488             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11489             // about the process state of the isolated UID *before* it is registered with the
11490             // owning application.
11491             mBatteryStatsService.addIsolatedUid(uid, info.uid);
11492         }
11493         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11494         if (!mBooted && !mBooting
11495                 && userId == UserHandle.USER_SYSTEM
11496                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11497             r.persistent = true;
11498         }
11499         addProcessNameLocked(r);
11500         return r;
11501     }
11502 
addAppLocked(ApplicationInfo info, boolean isolated, String abiOverride)11503     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11504             String abiOverride) {
11505         ProcessRecord app;
11506         if (!isolated) {
11507             app = getProcessRecordLocked(info.processName, info.uid, true);
11508         } else {
11509             app = null;
11510         }
11511 
11512         if (app == null) {
11513             app = newProcessRecordLocked(info, null, isolated, 0);
11514             updateLruProcessLocked(app, false, null);
11515             updateOomAdjLocked();
11516         }
11517 
11518         // This package really, really can not be stopped.
11519         try {
11520             AppGlobals.getPackageManager().setPackageStoppedState(
11521                     info.packageName, false, UserHandle.getUserId(app.uid));
11522         } catch (RemoteException e) {
11523         } catch (IllegalArgumentException e) {
11524             Slog.w(TAG, "Failed trying to unstop package "
11525                     + info.packageName + ": " + e);
11526         }
11527 
11528         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11529             app.persistent = true;
11530             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11531         }
11532         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11533             mPersistentStartingProcesses.add(app);
11534             startProcessLocked(app, "added application", app.processName, abiOverride,
11535                     null /* entryPoint */, null /* entryPointArgs */);
11536         }
11537 
11538         return app;
11539     }
11540 
unhandledBack()11541     public void unhandledBack() {
11542         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11543                 "unhandledBack()");
11544 
11545         synchronized(this) {
11546             final long origId = Binder.clearCallingIdentity();
11547             try {
11548                 getFocusedStack().unhandledBackLocked();
11549             } finally {
11550                 Binder.restoreCallingIdentity(origId);
11551             }
11552         }
11553     }
11554 
openContentUri(Uri uri)11555     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11556         enforceNotIsolatedCaller("openContentUri");
11557         final int userId = UserHandle.getCallingUserId();
11558         String name = uri.getAuthority();
11559         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11560         ParcelFileDescriptor pfd = null;
11561         if (cph != null) {
11562             // We record the binder invoker's uid in thread-local storage before
11563             // going to the content provider to open the file.  Later, in the code
11564             // that handles all permissions checks, we look for this uid and use
11565             // that rather than the Activity Manager's own uid.  The effect is that
11566             // we do the check against the caller's permissions even though it looks
11567             // to the content provider like the Activity Manager itself is making
11568             // the request.
11569             Binder token = new Binder();
11570             sCallerIdentity.set(new Identity(
11571                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11572             try {
11573                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11574             } catch (FileNotFoundException e) {
11575                 // do nothing; pfd will be returned null
11576             } finally {
11577                 // Ensure that whatever happens, we clean up the identity state
11578                 sCallerIdentity.remove();
11579                 // Ensure we're done with the provider.
11580                 removeContentProviderExternalUnchecked(name, null, userId);
11581             }
11582         } else {
11583             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11584         }
11585         return pfd;
11586     }
11587 
11588     // Actually is sleeping or shutting down or whatever else in the future
11589     // is an inactive state.
isSleepingOrShuttingDownLocked()11590     boolean isSleepingOrShuttingDownLocked() {
11591         return isSleepingLocked() || mShuttingDown;
11592     }
11593 
isShuttingDownLocked()11594     boolean isShuttingDownLocked() {
11595         return mShuttingDown;
11596     }
11597 
isSleepingLocked()11598     boolean isSleepingLocked() {
11599         return mSleeping;
11600     }
11601 
onWakefulnessChanged(int wakefulness)11602     void onWakefulnessChanged(int wakefulness) {
11603         synchronized(this) {
11604             mWakefulness = wakefulness;
11605             updateSleepIfNeededLocked();
11606         }
11607     }
11608 
finishRunningVoiceLocked()11609     void finishRunningVoiceLocked() {
11610         if (mRunningVoice != null) {
11611             mRunningVoice = null;
11612             mVoiceWakeLock.release();
11613             updateSleepIfNeededLocked();
11614         }
11615     }
11616 
startTimeTrackingFocusedActivityLocked()11617     void startTimeTrackingFocusedActivityLocked() {
11618         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11619             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11620         }
11621     }
11622 
updateSleepIfNeededLocked()11623     void updateSleepIfNeededLocked() {
11624         if (mSleeping && !shouldSleepLocked()) {
11625             mSleeping = false;
11626             startTimeTrackingFocusedActivityLocked();
11627             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11628             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11629             updateOomAdjLocked();
11630         } else if (!mSleeping && shouldSleepLocked()) {
11631             mSleeping = true;
11632             if (mCurAppTimeTracker != null) {
11633                 mCurAppTimeTracker.stop();
11634             }
11635             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11636             mStackSupervisor.goingToSleepLocked();
11637             updateOomAdjLocked();
11638 
11639             // Initialize the wake times of all processes.
11640             checkExcessivePowerUsageLocked(false);
11641             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11642             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11643             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11644         }
11645     }
11646 
shouldSleepLocked()11647     private boolean shouldSleepLocked() {
11648         // Resume applications while running a voice interactor.
11649         if (mRunningVoice != null) {
11650             return false;
11651         }
11652 
11653         // TODO: Transform the lock screen state into a sleep token instead.
11654         switch (mWakefulness) {
11655             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11656             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11657             case PowerManagerInternal.WAKEFULNESS_DOZING:
11658                 // Pause applications whenever the lock screen is shown or any sleep
11659                 // tokens have been acquired.
11660                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11661             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11662             default:
11663                 // If we're asleep then pause applications unconditionally.
11664                 return true;
11665         }
11666     }
11667 
11668     /** Pokes the task persister. */
notifyTaskPersisterLocked(TaskRecord task, boolean flush)11669     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11670         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11671     }
11672 
11673     /** Notifies all listeners when the task stack has changed. */
notifyTaskStackChangedLocked()11674     void notifyTaskStackChangedLocked() {
11675         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11676         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11677         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11678         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11679     }
11680 
11681     /** Notifies all listeners when an Activity is pinned. */
notifyActivityPinnedLocked()11682     void notifyActivityPinnedLocked() {
11683         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11684         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11685     }
11686 
11687     /**
11688      * Notifies all listeners when an attempt was made to start an an activity that is already
11689      * running in the pinned stack and the activity was not actually started, but the task is
11690      * either brought to the front or a new Intent is delivered to it.
11691      */
notifyPinnedActivityRestartAttemptLocked()11692     void notifyPinnedActivityRestartAttemptLocked() {
11693         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11694         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11695     }
11696 
11697     /** Notifies all listeners when the pinned stack animation ends. */
11698     @Override
notifyPinnedStackAnimationEnded()11699     public void notifyPinnedStackAnimationEnded() {
11700         synchronized (this) {
11701             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11702             mHandler.obtainMessage(
11703                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11704         }
11705     }
11706 
11707     @Override
notifyCleartextNetwork(int uid, byte[] firstPacket)11708     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11709         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11710     }
11711 
11712     @Override
shutdown(int timeout)11713     public boolean shutdown(int timeout) {
11714         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11715                 != PackageManager.PERMISSION_GRANTED) {
11716             throw new SecurityException("Requires permission "
11717                     + android.Manifest.permission.SHUTDOWN);
11718         }
11719 
11720         boolean timedout = false;
11721 
11722         synchronized(this) {
11723             mShuttingDown = true;
11724             updateEventDispatchingLocked();
11725             timedout = mStackSupervisor.shutdownLocked(timeout);
11726         }
11727 
11728         mAppOpsService.shutdown();
11729         if (mUsageStatsService != null) {
11730             mUsageStatsService.prepareShutdown();
11731         }
11732         mBatteryStatsService.shutdown();
11733         synchronized (this) {
11734             mProcessStats.shutdownLocked();
11735             notifyTaskPersisterLocked(null, true);
11736         }
11737 
11738         return timedout;
11739     }
11740 
activitySlept(IBinder token)11741     public final void activitySlept(IBinder token) {
11742         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11743 
11744         final long origId = Binder.clearCallingIdentity();
11745 
11746         synchronized (this) {
11747             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11748             if (r != null) {
11749                 mStackSupervisor.activitySleptLocked(r);
11750             }
11751         }
11752 
11753         Binder.restoreCallingIdentity(origId);
11754     }
11755 
lockScreenShownToString()11756     private String lockScreenShownToString() {
11757         switch (mLockScreenShown) {
11758             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11759             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11760             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11761             default: return "Unknown=" + mLockScreenShown;
11762         }
11763     }
11764 
logLockScreen(String msg)11765     void logLockScreen(String msg) {
11766         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11767                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11768                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11769                 + " mSleeping=" + mSleeping);
11770     }
11771 
startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid)11772     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11773         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11774         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11775         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11776             boolean wasRunningVoice = mRunningVoice != null;
11777             mRunningVoice = session;
11778             if (!wasRunningVoice) {
11779                 mVoiceWakeLock.acquire();
11780                 updateSleepIfNeededLocked();
11781             }
11782         }
11783     }
11784 
updateEventDispatchingLocked()11785     private void updateEventDispatchingLocked() {
11786         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11787     }
11788 
setLockScreenShown(boolean showing, boolean occluded)11789     public void setLockScreenShown(boolean showing, boolean occluded) {
11790         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11791                 != PackageManager.PERMISSION_GRANTED) {
11792             throw new SecurityException("Requires permission "
11793                     + android.Manifest.permission.DEVICE_POWER);
11794         }
11795 
11796         synchronized(this) {
11797             long ident = Binder.clearCallingIdentity();
11798             try {
11799                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11800                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11801                 if (showing && occluded) {
11802                     // The lock screen is currently showing, but is occluded by a window that can
11803                     // show on top of the lock screen. In this can we want to dismiss the docked
11804                     // stack since it will be complicated/risky to try to put the activity on top
11805                     // of the lock screen in the right fullscreen configuration.
11806                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11807                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11808                 }
11809 
11810                 updateSleepIfNeededLocked();
11811             } finally {
11812                 Binder.restoreCallingIdentity(ident);
11813             }
11814         }
11815     }
11816 
11817     @Override
notifyLockedProfile(@serIdInt int userId)11818     public void notifyLockedProfile(@UserIdInt int userId) {
11819         try {
11820             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11821                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11822             }
11823         } catch (RemoteException ex) {
11824             throw new SecurityException("Fail to check is caller a privileged app", ex);
11825         }
11826 
11827         synchronized (this) {
11828             if (mStackSupervisor.isUserLockedProfile(userId)) {
11829                 final long ident = Binder.clearCallingIdentity();
11830                 try {
11831                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11832 
11833                     // Drop locked freeform tasks out into the fullscreen stack.
11834                     // TODO: Redact the tasks in place. It's much better to keep them on the screen
11835                     //       where they were before, but in an obscured state.
11836                     mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11837 
11838                     if (mUserController.isLockScreenDisabled(currentUserId)) {
11839                         // If there is no device lock, we will show the profile's credential page.
11840                         mActivityStarter.showConfirmDeviceCredential(userId);
11841                     } else {
11842                         // Showing launcher to avoid user entering credential twice.
11843                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11844                     }
11845                 } finally {
11846                     Binder.restoreCallingIdentity(ident);
11847                 }
11848             }
11849         }
11850     }
11851 
11852     @Override
startConfirmDeviceCredentialIntent(Intent intent)11853     public void startConfirmDeviceCredentialIntent(Intent intent) {
11854         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11855         synchronized (this) {
11856             final long ident = Binder.clearCallingIdentity();
11857             try {
11858                 mActivityStarter.startConfirmCredentialIntent(intent);
11859             } finally {
11860                 Binder.restoreCallingIdentity(ident);
11861             }
11862         }
11863     }
11864 
11865     @Override
stopAppSwitches()11866     public void stopAppSwitches() {
11867         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11868                 != PackageManager.PERMISSION_GRANTED) {
11869             throw new SecurityException("viewquires permission "
11870                     + android.Manifest.permission.STOP_APP_SWITCHES);
11871         }
11872 
11873         synchronized(this) {
11874             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11875                     + APP_SWITCH_DELAY_TIME;
11876             mDidAppSwitch = false;
11877             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11878             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11879             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11880         }
11881     }
11882 
resumeAppSwitches()11883     public void resumeAppSwitches() {
11884         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11885                 != PackageManager.PERMISSION_GRANTED) {
11886             throw new SecurityException("Requires permission "
11887                     + android.Manifest.permission.STOP_APP_SWITCHES);
11888         }
11889 
11890         synchronized(this) {
11891             // Note that we don't execute any pending app switches... we will
11892             // let those wait until either the timeout, or the next start
11893             // activity request.
11894             mAppSwitchesAllowedTime = 0;
11895         }
11896     }
11897 
checkAppSwitchAllowedLocked(int sourcePid, int sourceUid, int callingPid, int callingUid, String name)11898     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11899             int callingPid, int callingUid, String name) {
11900         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11901             return true;
11902         }
11903 
11904         int perm = checkComponentPermission(
11905                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11906                 sourceUid, -1, true);
11907         if (perm == PackageManager.PERMISSION_GRANTED) {
11908             return true;
11909         }
11910 
11911         // If the actual IPC caller is different from the logical source, then
11912         // also see if they are allowed to control app switches.
11913         if (callingUid != -1 && callingUid != sourceUid) {
11914             perm = checkComponentPermission(
11915                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11916                     callingUid, -1, true);
11917             if (perm == PackageManager.PERMISSION_GRANTED) {
11918                 return true;
11919             }
11920         }
11921 
11922         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11923         return false;
11924     }
11925 
setDebugApp(String packageName, boolean waitForDebugger, boolean persistent)11926     public void setDebugApp(String packageName, boolean waitForDebugger,
11927             boolean persistent) {
11928         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
11929                 "setDebugApp()");
11930 
11931         long ident = Binder.clearCallingIdentity();
11932         try {
11933             // Note that this is not really thread safe if there are multiple
11934             // callers into it at the same time, but that's not a situation we
11935             // care about.
11936             if (persistent) {
11937                 final ContentResolver resolver = mContext.getContentResolver();
11938                 Settings.Global.putString(
11939                     resolver, Settings.Global.DEBUG_APP,
11940                     packageName);
11941                 Settings.Global.putInt(
11942                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
11943                     waitForDebugger ? 1 : 0);
11944             }
11945 
11946             synchronized (this) {
11947                 if (!persistent) {
11948                     mOrigDebugApp = mDebugApp;
11949                     mOrigWaitForDebugger = mWaitForDebugger;
11950                 }
11951                 mDebugApp = packageName;
11952                 mWaitForDebugger = waitForDebugger;
11953                 mDebugTransient = !persistent;
11954                 if (packageName != null) {
11955                     forceStopPackageLocked(packageName, -1, false, false, true, true,
11956                             false, UserHandle.USER_ALL, "set debug app");
11957                 }
11958             }
11959         } finally {
11960             Binder.restoreCallingIdentity(ident);
11961         }
11962     }
11963 
setTrackAllocationApp(ApplicationInfo app, String processName)11964     void setTrackAllocationApp(ApplicationInfo app, String processName) {
11965         synchronized (this) {
11966             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11967             if (!isDebuggable) {
11968                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11969                     throw new SecurityException("Process not debuggable: " + app.packageName);
11970                 }
11971             }
11972 
11973             mTrackAllocationApp = processName;
11974         }
11975     }
11976 
setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo)11977     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
11978         synchronized (this) {
11979             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
11980             if (!isDebuggable) {
11981                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
11982                     throw new SecurityException("Process not debuggable: " + app.packageName);
11983                 }
11984             }
11985             mProfileApp = processName;
11986             mProfileFile = profilerInfo.profileFile;
11987             if (mProfileFd != null) {
11988                 try {
11989                     mProfileFd.close();
11990                 } catch (IOException e) {
11991                 }
11992                 mProfileFd = null;
11993             }
11994             mProfileFd = profilerInfo.profileFd;
11995             mSamplingInterval = profilerInfo.samplingInterval;
11996             mAutoStopProfiler = profilerInfo.autoStopProfiler;
11997             mProfileType = 0;
11998         }
11999     }
12000 
setNativeDebuggingAppLocked(ApplicationInfo app, String processName)12001     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12002         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12003         if (!isDebuggable) {
12004             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12005                 throw new SecurityException("Process not debuggable: " + app.packageName);
12006             }
12007         }
12008         mNativeDebuggingApp = processName;
12009     }
12010 
12011     @Override
setAlwaysFinish(boolean enabled)12012     public void setAlwaysFinish(boolean enabled) {
12013         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12014                 "setAlwaysFinish()");
12015 
12016         long ident = Binder.clearCallingIdentity();
12017         try {
12018             Settings.Global.putInt(
12019                     mContext.getContentResolver(),
12020                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12021 
12022             synchronized (this) {
12023                 mAlwaysFinishActivities = enabled;
12024             }
12025         } finally {
12026             Binder.restoreCallingIdentity(ident);
12027         }
12028     }
12029 
12030     @Override
setLenientBackgroundCheck(boolean enabled)12031     public void setLenientBackgroundCheck(boolean enabled) {
12032         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12033                 "setLenientBackgroundCheck()");
12034 
12035         long ident = Binder.clearCallingIdentity();
12036         try {
12037             Settings.Global.putInt(
12038                     mContext.getContentResolver(),
12039                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12040 
12041             synchronized (this) {
12042                 mLenientBackgroundCheck = enabled;
12043             }
12044         } finally {
12045             Binder.restoreCallingIdentity(ident);
12046         }
12047     }
12048 
12049     @Override
setActivityController(IActivityController controller, boolean imAMonkey)12050     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12051         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12052                 "setActivityController()");
12053         synchronized (this) {
12054             mController = controller;
12055             mControllerIsAMonkey = imAMonkey;
12056             Watchdog.getInstance().setActivityController(controller);
12057         }
12058     }
12059 
12060     @Override
setUserIsMonkey(boolean userIsMonkey)12061     public void setUserIsMonkey(boolean userIsMonkey) {
12062         synchronized (this) {
12063             synchronized (mPidsSelfLocked) {
12064                 final int callingPid = Binder.getCallingPid();
12065                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12066                 if (precessRecord == null) {
12067                     throw new SecurityException("Unknown process: " + callingPid);
12068                 }
12069                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
12070                     throw new SecurityException("Only an instrumentation process "
12071                             + "with a UiAutomation can call setUserIsMonkey");
12072                 }
12073             }
12074             mUserIsMonkey = userIsMonkey;
12075         }
12076     }
12077 
12078     @Override
isUserAMonkey()12079     public boolean isUserAMonkey() {
12080         synchronized (this) {
12081             // If there is a controller also implies the user is a monkey.
12082             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12083         }
12084     }
12085 
requestBugReport(int bugreportType)12086     public void requestBugReport(int bugreportType) {
12087         String service = null;
12088         switch (bugreportType) {
12089             case ActivityManager.BUGREPORT_OPTION_FULL:
12090                 service = "bugreport";
12091                 break;
12092             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12093                 service = "bugreportplus";
12094                 break;
12095             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12096                 service = "bugreportremote";
12097                 break;
12098             case ActivityManager.BUGREPORT_OPTION_WEAR:
12099                 service = "bugreportwear";
12100                 break;
12101         }
12102         if (service == null) {
12103             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12104                     + bugreportType);
12105         }
12106         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12107         SystemProperties.set("ctl.start", service);
12108     }
12109 
getInputDispatchingTimeoutLocked(ActivityRecord r)12110     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12111         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12112     }
12113 
getInputDispatchingTimeoutLocked(ProcessRecord r)12114     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12115         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12116             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12117         }
12118         return KEY_DISPATCHING_TIMEOUT;
12119     }
12120 
12121     @Override
inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason)12122     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12123         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12124                 != PackageManager.PERMISSION_GRANTED) {
12125             throw new SecurityException("Requires permission "
12126                     + android.Manifest.permission.FILTER_EVENTS);
12127         }
12128         ProcessRecord proc;
12129         long timeout;
12130         synchronized (this) {
12131             synchronized (mPidsSelfLocked) {
12132                 proc = mPidsSelfLocked.get(pid);
12133             }
12134             timeout = getInputDispatchingTimeoutLocked(proc);
12135         }
12136 
12137         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12138             return -1;
12139         }
12140 
12141         return timeout;
12142     }
12143 
12144     /**
12145      * Handle input dispatching timeouts.
12146      * Returns whether input dispatching should be aborted or not.
12147      */
inputDispatchingTimedOut(final ProcessRecord proc, final ActivityRecord activity, final ActivityRecord parent, final boolean aboveSystem, String reason)12148     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12149             final ActivityRecord activity, final ActivityRecord parent,
12150             final boolean aboveSystem, String reason) {
12151         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12152                 != PackageManager.PERMISSION_GRANTED) {
12153             throw new SecurityException("Requires permission "
12154                     + android.Manifest.permission.FILTER_EVENTS);
12155         }
12156 
12157         final String annotation;
12158         if (reason == null) {
12159             annotation = "Input dispatching timed out";
12160         } else {
12161             annotation = "Input dispatching timed out (" + reason + ")";
12162         }
12163 
12164         if (proc != null) {
12165             synchronized (this) {
12166                 if (proc.debugging) {
12167                     return false;
12168                 }
12169 
12170                 if (mDidDexOpt) {
12171                     // Give more time since we were dexopting.
12172                     mDidDexOpt = false;
12173                     return false;
12174                 }
12175 
12176                 if (proc.instrumentationClass != null) {
12177                     Bundle info = new Bundle();
12178                     info.putString("shortMsg", "keyDispatchingTimedOut");
12179                     info.putString("longMsg", annotation);
12180                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12181                     return true;
12182                 }
12183             }
12184             mHandler.post(new Runnable() {
12185                 @Override
12186                 public void run() {
12187                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12188                 }
12189             });
12190         }
12191 
12192         return true;
12193     }
12194 
12195     @Override
getAssistContextExtras(int requestType)12196     public Bundle getAssistContextExtras(int requestType) {
12197         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12198                 null, null, true /* focused */, true /* newSessionId */,
12199                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12200         if (pae == null) {
12201             return null;
12202         }
12203         synchronized (pae) {
12204             while (!pae.haveResult) {
12205                 try {
12206                     pae.wait();
12207                 } catch (InterruptedException e) {
12208                 }
12209             }
12210         }
12211         synchronized (this) {
12212             buildAssistBundleLocked(pae, pae.result);
12213             mPendingAssistExtras.remove(pae);
12214             mUiHandler.removeCallbacks(pae);
12215         }
12216         return pae.extras;
12217     }
12218 
12219     @Override
isAssistDataAllowedOnCurrentActivity()12220     public boolean isAssistDataAllowedOnCurrentActivity() {
12221         int userId;
12222         synchronized (this) {
12223             userId = mUserController.getCurrentUserIdLocked();
12224             ActivityRecord activity = getFocusedStack().topActivity();
12225             if (activity == null) {
12226                 return false;
12227             }
12228             userId = activity.userId;
12229         }
12230         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12231                 Context.DEVICE_POLICY_SERVICE);
12232         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12233     }
12234 
12235     @Override
showAssistFromActivity(IBinder token, Bundle args)12236     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12237         long ident = Binder.clearCallingIdentity();
12238         try {
12239             synchronized (this) {
12240                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12241                 ActivityRecord top = getFocusedStack().topActivity();
12242                 if (top != caller) {
12243                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12244                             + " is not current top " + top);
12245                     return false;
12246                 }
12247                 if (!top.nowVisible) {
12248                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12249                             + " is not visible");
12250                     return false;
12251                 }
12252             }
12253             AssistUtils utils = new AssistUtils(mContext);
12254             return utils.showSessionForActiveService(args,
12255                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12256         } finally {
12257             Binder.restoreCallingIdentity(ident);
12258         }
12259     }
12260 
12261     @Override
requestAssistContextExtras(int requestType, IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId)12262     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12263             Bundle receiverExtras,
12264             IBinder activityToken, boolean focused, boolean newSessionId) {
12265         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12266                 activityToken, focused, newSessionId,
12267                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12268                 != null;
12269     }
12270 
enqueueAssistContext(int requestType, Intent intent, String hint, IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken, boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout)12271     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12272             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12273             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12274         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12275                 "enqueueAssistContext()");
12276         synchronized (this) {
12277             ActivityRecord activity = getFocusedStack().topActivity();
12278             if (activity == null) {
12279                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12280                 return null;
12281             }
12282             if (activity.app == null || activity.app.thread == null) {
12283                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12284                 return null;
12285             }
12286             if (focused) {
12287                 if (activityToken != null) {
12288                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12289                     if (activity != caller) {
12290                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12291                                 + " is not current top " + activity);
12292                         return null;
12293                     }
12294                 }
12295             } else {
12296                 activity = ActivityRecord.forTokenLocked(activityToken);
12297                 if (activity == null) {
12298                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12299                             + " couldn't be found");
12300                     return null;
12301                 }
12302             }
12303 
12304             PendingAssistExtras pae;
12305             Bundle extras = new Bundle();
12306             if (args != null) {
12307                 extras.putAll(args);
12308             }
12309             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12310             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12311             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12312                     userHandle);
12313             // Increment the sessionId if necessary
12314             if (newSessionId) {
12315                 mViSessionId++;
12316             }
12317             try {
12318                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12319                         requestType, mViSessionId);
12320                 mPendingAssistExtras.add(pae);
12321                 mUiHandler.postDelayed(pae, timeout);
12322             } catch (RemoteException e) {
12323                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12324                 return null;
12325             }
12326             return pae;
12327         }
12328     }
12329 
pendingAssistExtrasTimedOut(PendingAssistExtras pae)12330     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12331         IResultReceiver receiver;
12332         synchronized (this) {
12333             mPendingAssistExtras.remove(pae);
12334             receiver = pae.receiver;
12335         }
12336         if (receiver != null) {
12337             // Caller wants result sent back to them.
12338             Bundle sendBundle = new Bundle();
12339             // At least return the receiver extras
12340             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12341                     pae.receiverExtras);
12342             try {
12343                 pae.receiver.send(0, sendBundle);
12344             } catch (RemoteException e) {
12345             }
12346         }
12347     }
12348 
buildAssistBundleLocked(PendingAssistExtras pae, Bundle result)12349     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12350         if (result != null) {
12351             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12352         }
12353         if (pae.hint != null) {
12354             pae.extras.putBoolean(pae.hint, true);
12355         }
12356     }
12357 
reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure, AssistContent content, Uri referrer)12358     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12359             AssistContent content, Uri referrer) {
12360         PendingAssistExtras pae = (PendingAssistExtras)token;
12361         synchronized (pae) {
12362             pae.result = extras;
12363             pae.structure = structure;
12364             pae.content = content;
12365             if (referrer != null) {
12366                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12367             }
12368             pae.haveResult = true;
12369             pae.notifyAll();
12370             if (pae.intent == null && pae.receiver == null) {
12371                 // Caller is just waiting for the result.
12372                 return;
12373             }
12374         }
12375 
12376         // We are now ready to launch the assist activity.
12377         IResultReceiver sendReceiver = null;
12378         Bundle sendBundle = null;
12379         synchronized (this) {
12380             buildAssistBundleLocked(pae, extras);
12381             boolean exists = mPendingAssistExtras.remove(pae);
12382             mUiHandler.removeCallbacks(pae);
12383             if (!exists) {
12384                 // Timed out.
12385                 return;
12386             }
12387             if ((sendReceiver=pae.receiver) != null) {
12388                 // Caller wants result sent back to them.
12389                 sendBundle = new Bundle();
12390                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12391                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12392                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12393                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12394                         pae.receiverExtras);
12395             }
12396         }
12397         if (sendReceiver != null) {
12398             try {
12399                 sendReceiver.send(0, sendBundle);
12400             } catch (RemoteException e) {
12401             }
12402             return;
12403         }
12404 
12405         long ident = Binder.clearCallingIdentity();
12406         try {
12407             pae.intent.replaceExtras(pae.extras);
12408             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12409                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
12410                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12411             closeSystemDialogs("assist");
12412             try {
12413                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12414             } catch (ActivityNotFoundException e) {
12415                 Slog.w(TAG, "No activity to handle assist action.", e);
12416             }
12417         } finally {
12418             Binder.restoreCallingIdentity(ident);
12419         }
12420     }
12421 
launchAssistIntent(Intent intent, int requestType, String hint, int userHandle, Bundle args)12422     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12423             Bundle args) {
12424         return enqueueAssistContext(requestType, intent, hint, null, null, null,
12425                 true /* focused */, true /* newSessionId */,
12426                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12427     }
12428 
registerProcessObserver(IProcessObserver observer)12429     public void registerProcessObserver(IProcessObserver observer) {
12430         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12431                 "registerProcessObserver()");
12432         synchronized (this) {
12433             mProcessObservers.register(observer);
12434         }
12435     }
12436 
12437     @Override
unregisterProcessObserver(IProcessObserver observer)12438     public void unregisterProcessObserver(IProcessObserver observer) {
12439         synchronized (this) {
12440             mProcessObservers.unregister(observer);
12441         }
12442     }
12443 
12444     @Override
registerUidObserver(IUidObserver observer, int which)12445     public void registerUidObserver(IUidObserver observer, int which) {
12446         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12447                 "registerUidObserver()");
12448         synchronized (this) {
12449             mUidObservers.register(observer, which);
12450         }
12451     }
12452 
12453     @Override
unregisterUidObserver(IUidObserver observer)12454     public void unregisterUidObserver(IUidObserver observer) {
12455         synchronized (this) {
12456             mUidObservers.unregister(observer);
12457         }
12458     }
12459 
12460     @Override
convertFromTranslucent(IBinder token)12461     public boolean convertFromTranslucent(IBinder token) {
12462         final long origId = Binder.clearCallingIdentity();
12463         try {
12464             synchronized (this) {
12465                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12466                 if (r == null) {
12467                     return false;
12468                 }
12469                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12470                 if (translucentChanged) {
12471                     r.task.stack.releaseBackgroundResources(r);
12472                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12473                 }
12474                 mWindowManager.setAppFullscreen(token, true);
12475                 return translucentChanged;
12476             }
12477         } finally {
12478             Binder.restoreCallingIdentity(origId);
12479         }
12480     }
12481 
12482     @Override
convertToTranslucent(IBinder token, ActivityOptions options)12483     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12484         final long origId = Binder.clearCallingIdentity();
12485         try {
12486             synchronized (this) {
12487                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12488                 if (r == null) {
12489                     return false;
12490                 }
12491                 int index = r.task.mActivities.lastIndexOf(r);
12492                 if (index > 0) {
12493                     ActivityRecord under = r.task.mActivities.get(index - 1);
12494                     under.returningOptions = options;
12495                 }
12496                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12497                 if (translucentChanged) {
12498                     r.task.stack.convertActivityToTranslucent(r);
12499                 }
12500                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12501                 mWindowManager.setAppFullscreen(token, false);
12502                 return translucentChanged;
12503             }
12504         } finally {
12505             Binder.restoreCallingIdentity(origId);
12506         }
12507     }
12508 
12509     @Override
requestVisibleBehind(IBinder token, boolean visible)12510     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12511         final long origId = Binder.clearCallingIdentity();
12512         try {
12513             synchronized (this) {
12514                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12515                 if (r != null) {
12516                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12517                 }
12518             }
12519             return false;
12520         } finally {
12521             Binder.restoreCallingIdentity(origId);
12522         }
12523     }
12524 
12525     @Override
isBackgroundVisibleBehind(IBinder token)12526     public boolean isBackgroundVisibleBehind(IBinder token) {
12527         final long origId = Binder.clearCallingIdentity();
12528         try {
12529             synchronized (this) {
12530                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12531                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12532                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12533                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12534                 return visible;
12535             }
12536         } finally {
12537             Binder.restoreCallingIdentity(origId);
12538         }
12539     }
12540 
12541     @Override
getActivityOptions(IBinder token)12542     public ActivityOptions getActivityOptions(IBinder token) {
12543         final long origId = Binder.clearCallingIdentity();
12544         try {
12545             synchronized (this) {
12546                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12547                 if (r != null) {
12548                     final ActivityOptions activityOptions = r.pendingOptions;
12549                     r.pendingOptions = null;
12550                     return activityOptions;
12551                 }
12552                 return null;
12553             }
12554         } finally {
12555             Binder.restoreCallingIdentity(origId);
12556         }
12557     }
12558 
12559     @Override
setImmersive(IBinder token, boolean immersive)12560     public void setImmersive(IBinder token, boolean immersive) {
12561         synchronized(this) {
12562             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12563             if (r == null) {
12564                 throw new IllegalArgumentException();
12565             }
12566             r.immersive = immersive;
12567 
12568             // update associated state if we're frontmost
12569             if (r == mFocusedActivity) {
12570                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12571                 applyUpdateLockStateLocked(r);
12572             }
12573         }
12574     }
12575 
12576     @Override
isImmersive(IBinder token)12577     public boolean isImmersive(IBinder token) {
12578         synchronized (this) {
12579             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12580             if (r == null) {
12581                 throw new IllegalArgumentException();
12582             }
12583             return r.immersive;
12584         }
12585     }
12586 
setVrThread(int tid)12587     public void setVrThread(int tid) {
12588         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12589             throw new UnsupportedOperationException("VR mode not supported on this device!");
12590         }
12591 
12592         synchronized (this) {
12593             ProcessRecord proc;
12594             synchronized (mPidsSelfLocked) {
12595                 final int pid = Binder.getCallingPid();
12596                 proc = mPidsSelfLocked.get(pid);
12597 
12598                 if (proc != null && mInVrMode && tid >= 0) {
12599                     // ensure the tid belongs to the process
12600                     if (!Process.isThreadInProcess(pid, tid)) {
12601                         throw new IllegalArgumentException("VR thread does not belong to process");
12602                     }
12603 
12604                     // reset existing VR thread to CFS if this thread still exists and belongs to
12605                     // the calling process
12606                     if (proc.vrThreadTid != 0
12607                             && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12608                         try {
12609                             Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12610                         } catch (IllegalArgumentException e) {
12611                             // Ignore this.  Only occurs in race condition where previous VR thread
12612                             // was destroyed during this method call.
12613                         }
12614                     }
12615 
12616                     proc.vrThreadTid = tid;
12617 
12618                     // promote to FIFO now if the tid is non-zero
12619                     try {
12620                         if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12621                             proc.vrThreadTid > 0) {
12622                             Process.setThreadScheduler(proc.vrThreadTid,
12623                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12624                         }
12625                     } catch (IllegalArgumentException e) {
12626                         Slog.e(TAG, "Failed to set scheduling policy, thread does"
12627                                + " not exist:\n" + e);
12628                     }
12629                 }
12630             }
12631         }
12632     }
12633 
12634     @Override
setRenderThread(int tid)12635     public void setRenderThread(int tid) {
12636         synchronized (this) {
12637             ProcessRecord proc;
12638             synchronized (mPidsSelfLocked) {
12639                 int pid = Binder.getCallingPid();
12640                 proc = mPidsSelfLocked.get(pid);
12641                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12642                     // ensure the tid belongs to the process
12643                     if (!Process.isThreadInProcess(pid, tid)) {
12644                         throw new IllegalArgumentException(
12645                             "Render thread does not belong to process");
12646                     }
12647                     proc.renderThreadTid = tid;
12648                     if (DEBUG_OOM_ADJ) {
12649                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12650                     }
12651                     // promote to FIFO now
12652                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12653                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12654                         if (mUseFifoUiScheduling) {
12655                             Process.setThreadScheduler(proc.renderThreadTid,
12656                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12657                         } else {
12658                             Process.setThreadPriority(proc.renderThreadTid, -10);
12659                         }
12660                     }
12661                 } else {
12662                     if (DEBUG_OOM_ADJ) {
12663                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12664                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
12665                                mUseFifoUiScheduling);
12666                     }
12667                 }
12668             }
12669         }
12670     }
12671 
12672     @Override
setVrMode(IBinder token, boolean enabled, ComponentName packageName)12673     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12674         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12675             throw new UnsupportedOperationException("VR mode not supported on this device!");
12676         }
12677 
12678         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12679 
12680         ActivityRecord r;
12681         synchronized (this) {
12682             r = ActivityRecord.isInStackLocked(token);
12683         }
12684 
12685         if (r == null) {
12686             throw new IllegalArgumentException();
12687         }
12688 
12689         int err;
12690         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12691                 VrManagerInternal.NO_ERROR) {
12692             return err;
12693         }
12694 
12695         synchronized(this) {
12696             r.requestedVrComponent = (enabled) ? packageName : null;
12697 
12698             // Update associated state if this activity is currently focused
12699             if (r == mFocusedActivity) {
12700                 applyUpdateVrModeLocked(r);
12701             }
12702             return 0;
12703         }
12704     }
12705 
12706     @Override
isVrModePackageEnabled(ComponentName packageName)12707     public boolean isVrModePackageEnabled(ComponentName packageName) {
12708         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12709             throw new UnsupportedOperationException("VR mode not supported on this device!");
12710         }
12711 
12712         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12713 
12714         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12715                 VrManagerInternal.NO_ERROR;
12716     }
12717 
isTopActivityImmersive()12718     public boolean isTopActivityImmersive() {
12719         enforceNotIsolatedCaller("startActivity");
12720         synchronized (this) {
12721             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12722             return (r != null) ? r.immersive : false;
12723         }
12724     }
12725 
12726     @Override
isTopOfTask(IBinder token)12727     public boolean isTopOfTask(IBinder token) {
12728         synchronized (this) {
12729             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12730             if (r == null) {
12731                 throw new IllegalArgumentException();
12732             }
12733             return r.task.getTopActivity() == r;
12734         }
12735     }
12736 
12737     @Override
setHasTopUi(boolean hasTopUi)12738     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12739         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12740             String msg = "Permission Denial: setHasTopUi() from pid="
12741                     + Binder.getCallingPid()
12742                     + ", uid=" + Binder.getCallingUid()
12743                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12744             Slog.w(TAG, msg);
12745             throw new SecurityException(msg);
12746         }
12747         final int pid = Binder.getCallingPid();
12748         final long origId = Binder.clearCallingIdentity();
12749         try {
12750             synchronized (this) {
12751                 boolean changed = false;
12752                 ProcessRecord pr;
12753                 synchronized (mPidsSelfLocked) {
12754                     pr = mPidsSelfLocked.get(pid);
12755                     if (pr == null) {
12756                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12757                         return;
12758                     }
12759                     if (pr.hasTopUi != hasTopUi) {
12760                         Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12761                         pr.hasTopUi = hasTopUi;
12762                         changed = true;
12763                     }
12764                 }
12765                 if (changed) {
12766                     updateOomAdjLocked(pr);
12767                 }
12768             }
12769         } finally {
12770             Binder.restoreCallingIdentity(origId);
12771         }
12772     }
12773 
enterSafeMode()12774     public final void enterSafeMode() {
12775         synchronized(this) {
12776             // It only makes sense to do this before the system is ready
12777             // and started launching other packages.
12778             if (!mSystemReady) {
12779                 try {
12780                     AppGlobals.getPackageManager().enterSafeMode();
12781                 } catch (RemoteException e) {
12782                 }
12783             }
12784 
12785             mSafeMode = true;
12786         }
12787     }
12788 
showSafeModeOverlay()12789     public final void showSafeModeOverlay() {
12790         View v = LayoutInflater.from(mContext).inflate(
12791                 com.android.internal.R.layout.safe_mode, null);
12792         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12793         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12794         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12795         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12796         lp.gravity = Gravity.BOTTOM | Gravity.START;
12797         lp.format = v.getBackground().getOpacity();
12798         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12799                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12800         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12801         ((WindowManager)mContext.getSystemService(
12802                 Context.WINDOW_SERVICE)).addView(v, lp);
12803     }
12804 
noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag)12805     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12806         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12807             return;
12808         }
12809         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12810         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12811         synchronized (stats) {
12812             if (mBatteryStatsService.isOnBattery()) {
12813                 mBatteryStatsService.enforceCallingPermission();
12814                 int MY_UID = Binder.getCallingUid();
12815                 final int uid;
12816                 if (sender == null) {
12817                     uid = sourceUid;
12818                 } else {
12819                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12820                 }
12821                 BatteryStatsImpl.Uid.Pkg pkg =
12822                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12823                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12824                 pkg.noteWakeupAlarmLocked(tag);
12825             }
12826         }
12827     }
12828 
noteAlarmStart(IIntentSender sender, int sourceUid, String tag)12829     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12830         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12831             return;
12832         }
12833         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12834         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12835         synchronized (stats) {
12836             mBatteryStatsService.enforceCallingPermission();
12837             int MY_UID = Binder.getCallingUid();
12838             final int uid;
12839             if (sender == null) {
12840                 uid = sourceUid;
12841             } else {
12842                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12843             }
12844             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12845         }
12846     }
12847 
noteAlarmFinish(IIntentSender sender, int sourceUid, String tag)12848     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12849         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12850             return;
12851         }
12852         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12853         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12854         synchronized (stats) {
12855             mBatteryStatsService.enforceCallingPermission();
12856             int MY_UID = Binder.getCallingUid();
12857             final int uid;
12858             if (sender == null) {
12859                 uid = sourceUid;
12860             } else {
12861                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12862             }
12863             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12864         }
12865     }
12866 
killPids(int[] pids, String pReason, boolean secure)12867     public boolean killPids(int[] pids, String pReason, boolean secure) {
12868         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12869             throw new SecurityException("killPids only available to the system");
12870         }
12871         String reason = (pReason == null) ? "Unknown" : pReason;
12872         // XXX Note: don't acquire main activity lock here, because the window
12873         // manager calls in with its locks held.
12874 
12875         boolean killed = false;
12876         synchronized (mPidsSelfLocked) {
12877             int worstType = 0;
12878             for (int i=0; i<pids.length; i++) {
12879                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12880                 if (proc != null) {
12881                     int type = proc.setAdj;
12882                     if (type > worstType) {
12883                         worstType = type;
12884                     }
12885                 }
12886             }
12887 
12888             // If the worst oom_adj is somewhere in the cached proc LRU range,
12889             // then constrain it so we will kill all cached procs.
12890             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12891                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12892                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12893             }
12894 
12895             // If this is not a secure call, don't let it kill processes that
12896             // are important.
12897             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12898                 worstType = ProcessList.SERVICE_ADJ;
12899             }
12900 
12901             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12902             for (int i=0; i<pids.length; i++) {
12903                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12904                 if (proc == null) {
12905                     continue;
12906                 }
12907                 int adj = proc.setAdj;
12908                 if (adj >= worstType && !proc.killedByAm) {
12909                     proc.kill(reason, true);
12910                     killed = true;
12911                 }
12912             }
12913         }
12914         return killed;
12915     }
12916 
12917     @Override
killUid(int appId, int userId, String reason)12918     public void killUid(int appId, int userId, String reason) {
12919         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12920         synchronized (this) {
12921             final long identity = Binder.clearCallingIdentity();
12922             try {
12923                 killPackageProcessesLocked(null, appId, userId,
12924                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12925                         reason != null ? reason : "kill uid");
12926             } finally {
12927                 Binder.restoreCallingIdentity(identity);
12928             }
12929         }
12930     }
12931 
12932     @Override
killProcessesBelowForeground(String reason)12933     public boolean killProcessesBelowForeground(String reason) {
12934         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12935             throw new SecurityException("killProcessesBelowForeground() only available to system");
12936         }
12937 
12938         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
12939     }
12940 
killProcessesBelowAdj(int belowAdj, String reason)12941     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
12942         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12943             throw new SecurityException("killProcessesBelowAdj() only available to system");
12944         }
12945 
12946         boolean killed = false;
12947         synchronized (mPidsSelfLocked) {
12948             final int size = mPidsSelfLocked.size();
12949             for (int i = 0; i < size; i++) {
12950                 final int pid = mPidsSelfLocked.keyAt(i);
12951                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
12952                 if (proc == null) continue;
12953 
12954                 final int adj = proc.setAdj;
12955                 if (adj > belowAdj && !proc.killedByAm) {
12956                     proc.kill(reason, true);
12957                     killed = true;
12958                 }
12959             }
12960         }
12961         return killed;
12962     }
12963 
12964     @Override
hang(final IBinder who, boolean allowRestart)12965     public void hang(final IBinder who, boolean allowRestart) {
12966         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
12967                 != PackageManager.PERMISSION_GRANTED) {
12968             throw new SecurityException("Requires permission "
12969                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
12970         }
12971 
12972         final IBinder.DeathRecipient death = new DeathRecipient() {
12973             @Override
12974             public void binderDied() {
12975                 synchronized (this) {
12976                     notifyAll();
12977                 }
12978             }
12979         };
12980 
12981         try {
12982             who.linkToDeath(death, 0);
12983         } catch (RemoteException e) {
12984             Slog.w(TAG, "hang: given caller IBinder is already dead.");
12985             return;
12986         }
12987 
12988         synchronized (this) {
12989             Watchdog.getInstance().setAllowRestart(allowRestart);
12990             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
12991             synchronized (death) {
12992                 while (who.isBinderAlive()) {
12993                     try {
12994                         death.wait();
12995                     } catch (InterruptedException e) {
12996                     }
12997                 }
12998             }
12999             Watchdog.getInstance().setAllowRestart(true);
13000         }
13001     }
13002 
13003     @Override
restart()13004     public void restart() {
13005         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13006                 != PackageManager.PERMISSION_GRANTED) {
13007             throw new SecurityException("Requires permission "
13008                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13009         }
13010 
13011         Log.i(TAG, "Sending shutdown broadcast...");
13012 
13013         BroadcastReceiver br = new BroadcastReceiver() {
13014             @Override public void onReceive(Context context, Intent intent) {
13015                 // Now the broadcast is done, finish up the low-level shutdown.
13016                 Log.i(TAG, "Shutting down activity manager...");
13017                 shutdown(10000);
13018                 Log.i(TAG, "Shutdown complete, restarting!");
13019                 Process.killProcess(Process.myPid());
13020                 System.exit(10);
13021             }
13022         };
13023 
13024         // First send the high-level shut down broadcast.
13025         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13026         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13027         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13028         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13029         mContext.sendOrderedBroadcastAsUser(intent,
13030                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13031         */
13032         br.onReceive(mContext, intent);
13033     }
13034 
getLowRamTimeSinceIdle(long now)13035     private long getLowRamTimeSinceIdle(long now) {
13036         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13037     }
13038 
13039     @Override
performIdleMaintenance()13040     public void performIdleMaintenance() {
13041         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13042                 != PackageManager.PERMISSION_GRANTED) {
13043             throw new SecurityException("Requires permission "
13044                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13045         }
13046 
13047         synchronized (this) {
13048             final long now = SystemClock.uptimeMillis();
13049             final long timeSinceLastIdle = now - mLastIdleTime;
13050             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13051             mLastIdleTime = now;
13052             mLowRamTimeSinceLastIdle = 0;
13053             if (mLowRamStartTime != 0) {
13054                 mLowRamStartTime = now;
13055             }
13056 
13057             StringBuilder sb = new StringBuilder(128);
13058             sb.append("Idle maintenance over ");
13059             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13060             sb.append(" low RAM for ");
13061             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13062             Slog.i(TAG, sb.toString());
13063 
13064             // If at least 1/3 of our time since the last idle period has been spent
13065             // with RAM low, then we want to kill processes.
13066             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13067 
13068             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13069                 ProcessRecord proc = mLruProcesses.get(i);
13070                 if (proc.notCachedSinceIdle) {
13071                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13072                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13073                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13074                         if (doKilling && proc.initialIdlePss != 0
13075                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13076                             sb = new StringBuilder(128);
13077                             sb.append("Kill");
13078                             sb.append(proc.processName);
13079                             sb.append(" in idle maint: pss=");
13080                             sb.append(proc.lastPss);
13081                             sb.append(", swapPss=");
13082                             sb.append(proc.lastSwapPss);
13083                             sb.append(", initialPss=");
13084                             sb.append(proc.initialIdlePss);
13085                             sb.append(", period=");
13086                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13087                             sb.append(", lowRamPeriod=");
13088                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13089                             Slog.wtfQuiet(TAG, sb.toString());
13090                             proc.kill("idle maint (pss " + proc.lastPss
13091                                     + " from " + proc.initialIdlePss + ")", true);
13092                         }
13093                     }
13094                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13095                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13096                     proc.notCachedSinceIdle = true;
13097                     proc.initialIdlePss = 0;
13098                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13099                             mTestPssMode, isSleepingLocked(), now);
13100                 }
13101             }
13102 
13103             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13104             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13105         }
13106     }
13107 
13108     @Override
sendIdleJobTrigger()13109     public void sendIdleJobTrigger() {
13110         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13111                 != PackageManager.PERMISSION_GRANTED) {
13112             throw new SecurityException("Requires permission "
13113                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13114         }
13115 
13116         final long ident = Binder.clearCallingIdentity();
13117         try {
13118             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13119                     .setPackage("android")
13120                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13121             broadcastIntent(null, intent, null, null, 0, null, null, null,
13122                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13123         } finally {
13124             Binder.restoreCallingIdentity(ident);
13125         }
13126     }
13127 
retrieveSettings()13128     private void retrieveSettings() {
13129         final ContentResolver resolver = mContext.getContentResolver();
13130         final boolean freeformWindowManagement =
13131                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13132                         || Settings.Global.getInt(
13133                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13134         final boolean supportsPictureInPicture =
13135                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13136 
13137         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13138         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13139         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13140         final boolean alwaysFinishActivities =
13141                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13142         final boolean lenientBackgroundCheck =
13143                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13144         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13145         final boolean forceResizable = Settings.Global.getInt(
13146                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13147         final boolean supportsLeanbackOnly =
13148                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13149 
13150         // Transfer any global setting for forcing RTL layout, into a System Property
13151         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13152 
13153         final Configuration configuration = new Configuration();
13154         Settings.System.getConfiguration(resolver, configuration);
13155         if (forceRtl) {
13156             // This will take care of setting the correct layout direction flags
13157             configuration.setLayoutDirection(configuration.locale);
13158         }
13159 
13160         synchronized (this) {
13161             mDebugApp = mOrigDebugApp = debugApp;
13162             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13163             mAlwaysFinishActivities = alwaysFinishActivities;
13164             mLenientBackgroundCheck = lenientBackgroundCheck;
13165             mSupportsLeanbackOnly = supportsLeanbackOnly;
13166             mForceResizableActivities = forceResizable;
13167             mWindowManager.setForceResizableTasks(mForceResizableActivities);
13168             if (supportsMultiWindow || forceResizable) {
13169                 mSupportsMultiWindow = true;
13170                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13171                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13172             } else {
13173                 mSupportsMultiWindow = false;
13174                 mSupportsFreeformWindowManagement = false;
13175                 mSupportsPictureInPicture = false;
13176             }
13177             // This happens before any activities are started, so we can
13178             // change mConfiguration in-place.
13179             updateConfigurationLocked(configuration, null, true);
13180             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13181                     "Initial config: " + mConfiguration);
13182 
13183             // Load resources only after the current configuration has been set.
13184             final Resources res = mContext.getResources();
13185             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13186             mThumbnailWidth = res.getDimensionPixelSize(
13187                     com.android.internal.R.dimen.thumbnail_width);
13188             mThumbnailHeight = res.getDimensionPixelSize(
13189                     com.android.internal.R.dimen.thumbnail_height);
13190             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13191                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
13192             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13193                     com.android.internal.R.string.config_appsNotReportingCrashes));
13194             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13195                 mFullscreenThumbnailScale = (float) res
13196                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13197                     (float) mConfiguration.screenWidthDp;
13198             } else {
13199                 mFullscreenThumbnailScale = res.getFraction(
13200                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13201             }
13202         }
13203     }
13204 
testIsSystemReady()13205     public boolean testIsSystemReady() {
13206         // no need to synchronize(this) just to read & return the value
13207         return mSystemReady;
13208     }
13209 
systemReady(final Runnable goingCallback)13210     public void systemReady(final Runnable goingCallback) {
13211         synchronized(this) {
13212             if (mSystemReady) {
13213                 // If we're done calling all the receivers, run the next "boot phase" passed in
13214                 // by the SystemServer
13215                 if (goingCallback != null) {
13216                     goingCallback.run();
13217                 }
13218                 return;
13219             }
13220 
13221             mLocalDeviceIdleController
13222                     = LocalServices.getService(DeviceIdleController.LocalService.class);
13223 
13224             // Make sure we have the current profile info, since it is needed for security checks.
13225             mUserController.onSystemReady();
13226             mRecentTasks.onSystemReadyLocked();
13227             mAppOpsService.systemReady();
13228             mSystemReady = true;
13229         }
13230 
13231         ArrayList<ProcessRecord> procsToKill = null;
13232         synchronized(mPidsSelfLocked) {
13233             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13234                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13235                 if (!isAllowedWhileBooting(proc.info)){
13236                     if (procsToKill == null) {
13237                         procsToKill = new ArrayList<ProcessRecord>();
13238                     }
13239                     procsToKill.add(proc);
13240                 }
13241             }
13242         }
13243 
13244         synchronized(this) {
13245             if (procsToKill != null) {
13246                 for (int i=procsToKill.size()-1; i>=0; i--) {
13247                     ProcessRecord proc = procsToKill.get(i);
13248                     Slog.i(TAG, "Removing system update proc: " + proc);
13249                     removeProcessLocked(proc, true, false, "system update done");
13250                 }
13251             }
13252 
13253             // Now that we have cleaned up any update processes, we
13254             // are ready to start launching real processes and know that
13255             // we won't trample on them any more.
13256             mProcessesReady = true;
13257         }
13258 
13259         Slog.i(TAG, "System now ready");
13260         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13261             SystemClock.uptimeMillis());
13262 
13263         synchronized(this) {
13264             // Make sure we have no pre-ready processes sitting around.
13265 
13266             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13267                 ResolveInfo ri = mContext.getPackageManager()
13268                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13269                                 STOCK_PM_FLAGS);
13270                 CharSequence errorMsg = null;
13271                 if (ri != null) {
13272                     ActivityInfo ai = ri.activityInfo;
13273                     ApplicationInfo app = ai.applicationInfo;
13274                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13275                         mTopAction = Intent.ACTION_FACTORY_TEST;
13276                         mTopData = null;
13277                         mTopComponent = new ComponentName(app.packageName,
13278                                 ai.name);
13279                     } else {
13280                         errorMsg = mContext.getResources().getText(
13281                                 com.android.internal.R.string.factorytest_not_system);
13282                     }
13283                 } else {
13284                     errorMsg = mContext.getResources().getText(
13285                             com.android.internal.R.string.factorytest_no_action);
13286                 }
13287                 if (errorMsg != null) {
13288                     mTopAction = null;
13289                     mTopData = null;
13290                     mTopComponent = null;
13291                     Message msg = Message.obtain();
13292                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13293                     msg.getData().putCharSequence("msg", errorMsg);
13294                     mUiHandler.sendMessage(msg);
13295                 }
13296             }
13297         }
13298 
13299         retrieveSettings();
13300         final int currentUserId;
13301         synchronized (this) {
13302             currentUserId = mUserController.getCurrentUserIdLocked();
13303             readGrantedUriPermissionsLocked();
13304         }
13305 
13306         if (goingCallback != null) goingCallback.run();
13307 
13308         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13309                 Integer.toString(currentUserId), currentUserId);
13310         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13311                 Integer.toString(currentUserId), currentUserId);
13312         mSystemServiceManager.startUser(currentUserId);
13313 
13314         synchronized (this) {
13315             // Only start up encryption-aware persistent apps; once user is
13316             // unlocked we'll come back around and start unaware apps
13317             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13318 
13319             // Start up initial activity.
13320             mBooting = true;
13321             // Enable home activity for system user, so that the system can always boot
13322             if (UserManager.isSplitSystemUser()) {
13323                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13324                 try {
13325                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13326                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13327                             UserHandle.USER_SYSTEM);
13328                 } catch (RemoteException e) {
13329                     throw e.rethrowAsRuntimeException();
13330                 }
13331             }
13332             startHomeActivityLocked(currentUserId, "systemReady");
13333 
13334             try {
13335                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13336                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13337                             + " data partition or your device will be unstable.");
13338                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13339                 }
13340             } catch (RemoteException e) {
13341             }
13342 
13343             if (!Build.isBuildConsistent()) {
13344                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13345                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13346             }
13347 
13348             long ident = Binder.clearCallingIdentity();
13349             try {
13350                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13351                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13352                         | Intent.FLAG_RECEIVER_FOREGROUND);
13353                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13354                 broadcastIntentLocked(null, null, intent,
13355                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13356                         null, false, false, MY_PID, Process.SYSTEM_UID,
13357                         currentUserId);
13358                 intent = new Intent(Intent.ACTION_USER_STARTING);
13359                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13360                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13361                 broadcastIntentLocked(null, null, intent,
13362                         null, new IIntentReceiver.Stub() {
13363                             @Override
13364                             public void performReceive(Intent intent, int resultCode, String data,
13365                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13366                                     throws RemoteException {
13367                             }
13368                         }, 0, null, null,
13369                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13370                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13371             } catch (Throwable t) {
13372                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13373             } finally {
13374                 Binder.restoreCallingIdentity(ident);
13375             }
13376             mStackSupervisor.resumeFocusedStackTopActivityLocked();
13377             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13378         }
13379     }
13380 
killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog)13381     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13382         synchronized (this) {
13383             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13384         }
13385     }
13386 
skipCurrentReceiverLocked(ProcessRecord app)13387     void skipCurrentReceiverLocked(ProcessRecord app) {
13388         for (BroadcastQueue queue : mBroadcastQueues) {
13389             queue.skipCurrentReceiverLocked(app);
13390         }
13391     }
13392 
13393     /**
13394      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13395      * The application process will exit immediately after this call returns.
13396      * @param app object of the crashing app, null for the system server
13397      * @param crashInfo describing the exception
13398      */
handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo)13399     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13400         ProcessRecord r = findAppProcess(app, "Crash");
13401         final String processName = app == null ? "system_server"
13402                 : (r == null ? "unknown" : r.processName);
13403 
13404         handleApplicationCrashInner("crash", r, processName, crashInfo);
13405     }
13406 
13407     /* Native crash reporting uses this inner version because it needs to be somewhat
13408      * decoupled from the AM-managed cleanup lifecycle
13409      */
handleApplicationCrashInner(String eventType, ProcessRecord r, String processName, ApplicationErrorReport.CrashInfo crashInfo)13410     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13411             ApplicationErrorReport.CrashInfo crashInfo) {
13412         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13413                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13414                 r == null ? -1 : r.info.flags,
13415                 crashInfo.exceptionClassName,
13416                 crashInfo.exceptionMessage,
13417                 crashInfo.throwFileName,
13418                 crashInfo.throwLineNumber);
13419 
13420         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13421 
13422         mAppErrors.crashApplication(r, crashInfo);
13423     }
13424 
handleApplicationStrictModeViolation( IBinder app, int violationMask, StrictMode.ViolationInfo info)13425     public void handleApplicationStrictModeViolation(
13426             IBinder app,
13427             int violationMask,
13428             StrictMode.ViolationInfo info) {
13429         ProcessRecord r = findAppProcess(app, "StrictMode");
13430         if (r == null) {
13431             return;
13432         }
13433 
13434         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13435             Integer stackFingerprint = info.hashCode();
13436             boolean logIt = true;
13437             synchronized (mAlreadyLoggedViolatedStacks) {
13438                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13439                     logIt = false;
13440                     // TODO: sub-sample into EventLog for these, with
13441                     // the info.durationMillis?  Then we'd get
13442                     // the relative pain numbers, without logging all
13443                     // the stack traces repeatedly.  We'd want to do
13444                     // likewise in the client code, which also does
13445                     // dup suppression, before the Binder call.
13446                 } else {
13447                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13448                         mAlreadyLoggedViolatedStacks.clear();
13449                     }
13450                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13451                 }
13452             }
13453             if (logIt) {
13454                 logStrictModeViolationToDropBox(r, info);
13455             }
13456         }
13457 
13458         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13459             AppErrorResult result = new AppErrorResult();
13460             synchronized (this) {
13461                 final long origId = Binder.clearCallingIdentity();
13462 
13463                 Message msg = Message.obtain();
13464                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13465                 HashMap<String, Object> data = new HashMap<String, Object>();
13466                 data.put("result", result);
13467                 data.put("app", r);
13468                 data.put("violationMask", violationMask);
13469                 data.put("info", info);
13470                 msg.obj = data;
13471                 mUiHandler.sendMessage(msg);
13472 
13473                 Binder.restoreCallingIdentity(origId);
13474             }
13475             int res = result.get();
13476             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13477         }
13478     }
13479 
13480     // Depending on the policy in effect, there could be a bunch of
13481     // these in quick succession so we try to batch these together to
13482     // minimize disk writes, number of dropbox entries, and maximize
13483     // compression, by having more fewer, larger records.
logStrictModeViolationToDropBox( ProcessRecord process, StrictMode.ViolationInfo info)13484     private void logStrictModeViolationToDropBox(
13485             ProcessRecord process,
13486             StrictMode.ViolationInfo info) {
13487         if (info == null) {
13488             return;
13489         }
13490         final boolean isSystemApp = process == null ||
13491                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13492                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13493         final String processName = process == null ? "unknown" : process.processName;
13494         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13495         final DropBoxManager dbox = (DropBoxManager)
13496                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13497 
13498         // Exit early if the dropbox isn't configured to accept this report type.
13499         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13500 
13501         boolean bufferWasEmpty;
13502         boolean needsFlush;
13503         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13504         synchronized (sb) {
13505             bufferWasEmpty = sb.length() == 0;
13506             appendDropBoxProcessHeaders(process, processName, sb);
13507             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13508             sb.append("System-App: ").append(isSystemApp).append("\n");
13509             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13510             if (info.violationNumThisLoop != 0) {
13511                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13512             }
13513             if (info.numAnimationsRunning != 0) {
13514                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13515             }
13516             if (info.broadcastIntentAction != null) {
13517                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13518             }
13519             if (info.durationMillis != -1) {
13520                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13521             }
13522             if (info.numInstances != -1) {
13523                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13524             }
13525             if (info.tags != null) {
13526                 for (String tag : info.tags) {
13527                     sb.append("Span-Tag: ").append(tag).append("\n");
13528                 }
13529             }
13530             sb.append("\n");
13531             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13532                 sb.append(info.crashInfo.stackTrace);
13533                 sb.append("\n");
13534             }
13535             if (info.message != null) {
13536                 sb.append(info.message);
13537                 sb.append("\n");
13538             }
13539 
13540             // Only buffer up to ~64k.  Various logging bits truncate
13541             // things at 128k.
13542             needsFlush = (sb.length() > 64 * 1024);
13543         }
13544 
13545         // Flush immediately if the buffer's grown too large, or this
13546         // is a non-system app.  Non-system apps are isolated with a
13547         // different tag & policy and not batched.
13548         //
13549         // Batching is useful during internal testing with
13550         // StrictMode settings turned up high.  Without batching,
13551         // thousands of separate files could be created on boot.
13552         if (!isSystemApp || needsFlush) {
13553             new Thread("Error dump: " + dropboxTag) {
13554                 @Override
13555                 public void run() {
13556                     String report;
13557                     synchronized (sb) {
13558                         report = sb.toString();
13559                         sb.delete(0, sb.length());
13560                         sb.trimToSize();
13561                     }
13562                     if (report.length() != 0) {
13563                         dbox.addText(dropboxTag, report);
13564                     }
13565                 }
13566             }.start();
13567             return;
13568         }
13569 
13570         // System app batching:
13571         if (!bufferWasEmpty) {
13572             // An existing dropbox-writing thread is outstanding, so
13573             // we don't need to start it up.  The existing thread will
13574             // catch the buffer appends we just did.
13575             return;
13576         }
13577 
13578         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13579         // (After this point, we shouldn't access AMS internal data structures.)
13580         new Thread("Error dump: " + dropboxTag) {
13581             @Override
13582             public void run() {
13583                 // 5 second sleep to let stacks arrive and be batched together
13584                 try {
13585                     Thread.sleep(5000);  // 5 seconds
13586                 } catch (InterruptedException e) {}
13587 
13588                 String errorReport;
13589                 synchronized (mStrictModeBuffer) {
13590                     errorReport = mStrictModeBuffer.toString();
13591                     if (errorReport.length() == 0) {
13592                         return;
13593                     }
13594                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13595                     mStrictModeBuffer.trimToSize();
13596                 }
13597                 dbox.addText(dropboxTag, errorReport);
13598             }
13599         }.start();
13600     }
13601 
13602     /**
13603      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13604      * @param app object of the crashing app, null for the system server
13605      * @param tag reported by the caller
13606      * @param system whether this wtf is coming from the system
13607      * @param crashInfo describing the context of the error
13608      * @return true if the process should exit immediately (WTF is fatal)
13609      */
handleApplicationWtf(final IBinder app, final String tag, boolean system, final ApplicationErrorReport.CrashInfo crashInfo)13610     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13611             final ApplicationErrorReport.CrashInfo crashInfo) {
13612         final int callingUid = Binder.getCallingUid();
13613         final int callingPid = Binder.getCallingPid();
13614 
13615         if (system) {
13616             // If this is coming from the system, we could very well have low-level
13617             // system locks held, so we want to do this all asynchronously.  And we
13618             // never want this to become fatal, so there is that too.
13619             mHandler.post(new Runnable() {
13620                 @Override public void run() {
13621                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13622                 }
13623             });
13624             return false;
13625         }
13626 
13627         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13628                 crashInfo);
13629 
13630         if (r != null && r.pid != Process.myPid() &&
13631                 Settings.Global.getInt(mContext.getContentResolver(),
13632                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13633             mAppErrors.crashApplication(r, crashInfo);
13634             return true;
13635         } else {
13636             return false;
13637         }
13638     }
13639 
handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag, final ApplicationErrorReport.CrashInfo crashInfo)13640     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13641             final ApplicationErrorReport.CrashInfo crashInfo) {
13642         final ProcessRecord r = findAppProcess(app, "WTF");
13643         final String processName = app == null ? "system_server"
13644                 : (r == null ? "unknown" : r.processName);
13645 
13646         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13647                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13648 
13649         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13650 
13651         return r;
13652     }
13653 
13654     /**
13655      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13656      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13657      */
findAppProcess(IBinder app, String reason)13658     private ProcessRecord findAppProcess(IBinder app, String reason) {
13659         if (app == null) {
13660             return null;
13661         }
13662 
13663         synchronized (this) {
13664             final int NP = mProcessNames.getMap().size();
13665             for (int ip=0; ip<NP; ip++) {
13666                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13667                 final int NA = apps.size();
13668                 for (int ia=0; ia<NA; ia++) {
13669                     ProcessRecord p = apps.valueAt(ia);
13670                     if (p.thread != null && p.thread.asBinder() == app) {
13671                         return p;
13672                     }
13673                 }
13674             }
13675 
13676             Slog.w(TAG, "Can't find mystery application for " + reason
13677                     + " from pid=" + Binder.getCallingPid()
13678                     + " uid=" + Binder.getCallingUid() + ": " + app);
13679             return null;
13680         }
13681     }
13682 
13683     /**
13684      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13685      * to append various headers to the dropbox log text.
13686      */
appendDropBoxProcessHeaders(ProcessRecord process, String processName, StringBuilder sb)13687     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13688             StringBuilder sb) {
13689         // Watchdog thread ends up invoking this function (with
13690         // a null ProcessRecord) to add the stack file to dropbox.
13691         // Do not acquire a lock on this (am) in such cases, as it
13692         // could cause a potential deadlock, if and when watchdog
13693         // is invoked due to unavailability of lock on am and it
13694         // would prevent watchdog from killing system_server.
13695         if (process == null) {
13696             sb.append("Process: ").append(processName).append("\n");
13697             return;
13698         }
13699         // Note: ProcessRecord 'process' is guarded by the service
13700         // instance.  (notably process.pkgList, which could otherwise change
13701         // concurrently during execution of this method)
13702         synchronized (this) {
13703             sb.append("Process: ").append(processName).append("\n");
13704             int flags = process.info.flags;
13705             IPackageManager pm = AppGlobals.getPackageManager();
13706             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13707             for (int ip=0; ip<process.pkgList.size(); ip++) {
13708                 String pkg = process.pkgList.keyAt(ip);
13709                 sb.append("Package: ").append(pkg);
13710                 try {
13711                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13712                     if (pi != null) {
13713                         sb.append(" v").append(pi.versionCode);
13714                         if (pi.versionName != null) {
13715                             sb.append(" (").append(pi.versionName).append(")");
13716                         }
13717                     }
13718                 } catch (RemoteException e) {
13719                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13720                 }
13721                 sb.append("\n");
13722             }
13723         }
13724     }
13725 
processClass(ProcessRecord process)13726     private static String processClass(ProcessRecord process) {
13727         if (process == null || process.pid == MY_PID) {
13728             return "system_server";
13729         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13730             return "system_app";
13731         } else {
13732             return "data_app";
13733         }
13734     }
13735 
13736     private volatile long mWtfClusterStart;
13737     private volatile int mWtfClusterCount;
13738 
13739     /**
13740      * Write a description of an error (crash, WTF, ANR) to the drop box.
13741      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13742      * @param process which caused the error, null means the system server
13743      * @param activity which triggered the error, null if unknown
13744      * @param parent activity related to the error, null if unknown
13745      * @param subject line related to the error, null if absent
13746      * @param report in long form describing the error, null if absent
13747      * @param dataFile text file to include in the report, null if none
13748      * @param crashInfo giving an application stack trace, null if absent
13749      */
addErrorToDropBox(String eventType, ProcessRecord process, String processName, ActivityRecord activity, ActivityRecord parent, String subject, final String report, final File dataFile, final ApplicationErrorReport.CrashInfo crashInfo)13750     public void addErrorToDropBox(String eventType,
13751             ProcessRecord process, String processName, ActivityRecord activity,
13752             ActivityRecord parent, String subject,
13753             final String report, final File dataFile,
13754             final ApplicationErrorReport.CrashInfo crashInfo) {
13755         // NOTE -- this must never acquire the ActivityManagerService lock,
13756         // otherwise the watchdog may be prevented from resetting the system.
13757 
13758         final String dropboxTag = processClass(process) + "_" + eventType;
13759         final DropBoxManager dbox = (DropBoxManager)
13760                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13761 
13762         // Exit early if the dropbox isn't configured to accept this report type.
13763         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13764 
13765         // Rate-limit how often we're willing to do the heavy lifting below to
13766         // collect and record logs; currently 5 logs per 10 second period.
13767         final long now = SystemClock.elapsedRealtime();
13768         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13769             mWtfClusterStart = now;
13770             mWtfClusterCount = 1;
13771         } else {
13772             if (mWtfClusterCount++ >= 5) return;
13773         }
13774 
13775         final StringBuilder sb = new StringBuilder(1024);
13776         appendDropBoxProcessHeaders(process, processName, sb);
13777         if (process != null) {
13778             sb.append("Foreground: ")
13779                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13780                     .append("\n");
13781         }
13782         if (activity != null) {
13783             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13784         }
13785         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13786             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13787         }
13788         if (parent != null && parent != activity) {
13789             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13790         }
13791         if (subject != null) {
13792             sb.append("Subject: ").append(subject).append("\n");
13793         }
13794         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13795         if (Debug.isDebuggerConnected()) {
13796             sb.append("Debugger: Connected\n");
13797         }
13798         sb.append("\n");
13799 
13800         // Do the rest in a worker thread to avoid blocking the caller on I/O
13801         // (After this point, we shouldn't access AMS internal data structures.)
13802         Thread worker = new Thread("Error dump: " + dropboxTag) {
13803             @Override
13804             public void run() {
13805                 if (report != null) {
13806                     sb.append(report);
13807                 }
13808 
13809                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13810                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13811                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13812                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13813 
13814                 if (dataFile != null && maxDataFileSize > 0) {
13815                     try {
13816                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13817                                     "\n\n[[TRUNCATED]]"));
13818                     } catch (IOException e) {
13819                         Slog.e(TAG, "Error reading " + dataFile, e);
13820                     }
13821                 }
13822                 if (crashInfo != null && crashInfo.stackTrace != null) {
13823                     sb.append(crashInfo.stackTrace);
13824                 }
13825 
13826                 if (lines > 0) {
13827                     sb.append("\n");
13828 
13829                     // Merge several logcat streams, and take the last N lines
13830                     InputStreamReader input = null;
13831                     try {
13832                         java.lang.Process logcat = new ProcessBuilder(
13833                                 "/system/bin/timeout", "-k", "15s", "10s",
13834                                 "/system/bin/logcat", "-v", "time", "-b", "events", "-b", "system",
13835                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13836                                         .redirectErrorStream(true).start();
13837 
13838                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13839                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13840                         input = new InputStreamReader(logcat.getInputStream());
13841 
13842                         int num;
13843                         char[] buf = new char[8192];
13844                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13845                     } catch (IOException e) {
13846                         Slog.e(TAG, "Error running logcat", e);
13847                     } finally {
13848                         if (input != null) try { input.close(); } catch (IOException e) {}
13849                     }
13850                 }
13851 
13852                 dbox.addText(dropboxTag, sb.toString());
13853             }
13854         };
13855 
13856         if (process == null) {
13857             // If process is null, we are being called from some internal code
13858             // and may be about to die -- run this synchronously.
13859             worker.run();
13860         } else {
13861             worker.start();
13862         }
13863     }
13864 
13865     @Override
getProcessesInErrorState()13866     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13867         enforceNotIsolatedCaller("getProcessesInErrorState");
13868         // assume our apps are happy - lazy create the list
13869         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13870 
13871         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13872                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13873         int userId = UserHandle.getUserId(Binder.getCallingUid());
13874 
13875         synchronized (this) {
13876 
13877             // iterate across all processes
13878             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13879                 ProcessRecord app = mLruProcesses.get(i);
13880                 if (!allUsers && app.userId != userId) {
13881                     continue;
13882                 }
13883                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13884                     // This one's in trouble, so we'll generate a report for it
13885                     // crashes are higher priority (in case there's a crash *and* an anr)
13886                     ActivityManager.ProcessErrorStateInfo report = null;
13887                     if (app.crashing) {
13888                         report = app.crashingReport;
13889                     } else if (app.notResponding) {
13890                         report = app.notRespondingReport;
13891                     }
13892 
13893                     if (report != null) {
13894                         if (errList == null) {
13895                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13896                         }
13897                         errList.add(report);
13898                     } else {
13899                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13900                                 " crashing = " + app.crashing +
13901                                 " notResponding = " + app.notResponding);
13902                     }
13903                 }
13904             }
13905         }
13906 
13907         return errList;
13908     }
13909 
procStateToImportance(int procState, int memAdj, ActivityManager.RunningAppProcessInfo currApp)13910     static int procStateToImportance(int procState, int memAdj,
13911             ActivityManager.RunningAppProcessInfo currApp) {
13912         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13913         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13914             currApp.lru = memAdj;
13915         } else {
13916             currApp.lru = 0;
13917         }
13918         return imp;
13919     }
13920 
fillInProcMemInfo(ProcessRecord app, ActivityManager.RunningAppProcessInfo outInfo)13921     private void fillInProcMemInfo(ProcessRecord app,
13922             ActivityManager.RunningAppProcessInfo outInfo) {
13923         outInfo.pid = app.pid;
13924         outInfo.uid = app.info.uid;
13925         if (mHeavyWeightProcess == app) {
13926             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
13927         }
13928         if (app.persistent) {
13929             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
13930         }
13931         if (app.activities.size() > 0) {
13932             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
13933         }
13934         outInfo.lastTrimLevel = app.trimMemoryLevel;
13935         int adj = app.curAdj;
13936         int procState = app.curProcState;
13937         outInfo.importance = procStateToImportance(procState, adj, outInfo);
13938         outInfo.importanceReasonCode = app.adjTypeCode;
13939         outInfo.processState = app.curProcState;
13940     }
13941 
13942     @Override
getRunningAppProcesses()13943     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
13944         enforceNotIsolatedCaller("getRunningAppProcesses");
13945 
13946         final int callingUid = Binder.getCallingUid();
13947 
13948         // Lazy instantiation of list
13949         List<ActivityManager.RunningAppProcessInfo> runList = null;
13950         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13951                 callingUid) == PackageManager.PERMISSION_GRANTED;
13952         final int userId = UserHandle.getUserId(callingUid);
13953         final boolean allUids = isGetTasksAllowed(
13954                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
13955 
13956         synchronized (this) {
13957             // Iterate across all processes
13958             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
13959                 ProcessRecord app = mLruProcesses.get(i);
13960                 if ((!allUsers && app.userId != userId)
13961                         || (!allUids && app.uid != callingUid)) {
13962                     continue;
13963                 }
13964                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
13965                     // Generate process state info for running application
13966                     ActivityManager.RunningAppProcessInfo currApp =
13967                         new ActivityManager.RunningAppProcessInfo(app.processName,
13968                                 app.pid, app.getPackageList());
13969                     fillInProcMemInfo(app, currApp);
13970                     if (app.adjSource instanceof ProcessRecord) {
13971                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
13972                         currApp.importanceReasonImportance =
13973                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
13974                                         app.adjSourceProcState);
13975                     } else if (app.adjSource instanceof ActivityRecord) {
13976                         ActivityRecord r = (ActivityRecord)app.adjSource;
13977                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
13978                     }
13979                     if (app.adjTarget instanceof ComponentName) {
13980                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
13981                     }
13982                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
13983                     //        + " lru=" + currApp.lru);
13984                     if (runList == null) {
13985                         runList = new ArrayList<>();
13986                     }
13987                     runList.add(currApp);
13988                 }
13989             }
13990         }
13991         return runList;
13992     }
13993 
13994     @Override
getRunningExternalApplications()13995     public List<ApplicationInfo> getRunningExternalApplications() {
13996         enforceNotIsolatedCaller("getRunningExternalApplications");
13997         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
13998         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
13999         if (runningApps != null && runningApps.size() > 0) {
14000             Set<String> extList = new HashSet<String>();
14001             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14002                 if (app.pkgList != null) {
14003                     for (String pkg : app.pkgList) {
14004                         extList.add(pkg);
14005                     }
14006                 }
14007             }
14008             IPackageManager pm = AppGlobals.getPackageManager();
14009             for (String pkg : extList) {
14010                 try {
14011                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14012                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14013                         retList.add(info);
14014                     }
14015                 } catch (RemoteException e) {
14016                 }
14017             }
14018         }
14019         return retList;
14020     }
14021 
14022     @Override
getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo)14023     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14024         enforceNotIsolatedCaller("getMyMemoryState");
14025         synchronized (this) {
14026             ProcessRecord proc;
14027             synchronized (mPidsSelfLocked) {
14028                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14029             }
14030             fillInProcMemInfo(proc, outInfo);
14031         }
14032     }
14033 
14034     @Override
getMemoryTrimLevel()14035     public int getMemoryTrimLevel() {
14036         enforceNotIsolatedCaller("getMyMemoryState");
14037         synchronized (this) {
14038             return mLastMemoryLevel;
14039         }
14040     }
14041 
14042     @Override
onShellCommand(FileDescriptor in, FileDescriptor out, FileDescriptor err, String[] args, ResultReceiver resultReceiver)14043     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14044             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14045         (new ActivityManagerShellCommand(this, false)).exec(
14046                 this, in, out, err, args, resultReceiver);
14047     }
14048 
14049     @Override
dump(FileDescriptor fd, PrintWriter pw, String[] args)14050     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14051         if (checkCallingPermission(android.Manifest.permission.DUMP)
14052                 != PackageManager.PERMISSION_GRANTED) {
14053             pw.println("Permission Denial: can't dump ActivityManager from from pid="
14054                     + Binder.getCallingPid()
14055                     + ", uid=" + Binder.getCallingUid()
14056                     + " without permission "
14057                     + android.Manifest.permission.DUMP);
14058             return;
14059         }
14060 
14061         boolean dumpAll = false;
14062         boolean dumpClient = false;
14063         boolean dumpCheckin = false;
14064         boolean dumpCheckinFormat = false;
14065         String dumpPackage = null;
14066 
14067         int opti = 0;
14068         while (opti < args.length) {
14069             String opt = args[opti];
14070             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14071                 break;
14072             }
14073             opti++;
14074             if ("-a".equals(opt)) {
14075                 dumpAll = true;
14076             } else if ("-c".equals(opt)) {
14077                 dumpClient = true;
14078             } else if ("-p".equals(opt)) {
14079                 if (opti < args.length) {
14080                     dumpPackage = args[opti];
14081                     opti++;
14082                 } else {
14083                     pw.println("Error: -p option requires package argument");
14084                     return;
14085                 }
14086                 dumpClient = true;
14087             } else if ("--checkin".equals(opt)) {
14088                 dumpCheckin = dumpCheckinFormat = true;
14089             } else if ("-C".equals(opt)) {
14090                 dumpCheckinFormat = true;
14091             } else if ("-h".equals(opt)) {
14092                 ActivityManagerShellCommand.dumpHelp(pw, true);
14093                 return;
14094             } else {
14095                 pw.println("Unknown argument: " + opt + "; use -h for help");
14096             }
14097         }
14098 
14099         long origId = Binder.clearCallingIdentity();
14100         boolean more = false;
14101         // Is the caller requesting to dump a particular piece of data?
14102         if (opti < args.length) {
14103             String cmd = args[opti];
14104             opti++;
14105             if ("activities".equals(cmd) || "a".equals(cmd)) {
14106                 synchronized (this) {
14107                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14108                 }
14109             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14110                 synchronized (this) {
14111                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14112                 }
14113             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14114                 String[] newArgs;
14115                 String name;
14116                 if (opti >= args.length) {
14117                     name = null;
14118                     newArgs = EMPTY_STRING_ARRAY;
14119                 } else {
14120                     dumpPackage = args[opti];
14121                     opti++;
14122                     newArgs = new String[args.length - opti];
14123                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14124                             args.length - opti);
14125                 }
14126                 synchronized (this) {
14127                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14128                 }
14129             } else if ("broadcast-stats".equals(cmd)) {
14130                 String[] newArgs;
14131                 String name;
14132                 if (opti >= args.length) {
14133                     name = null;
14134                     newArgs = EMPTY_STRING_ARRAY;
14135                 } else {
14136                     dumpPackage = args[opti];
14137                     opti++;
14138                     newArgs = new String[args.length - opti];
14139                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14140                             args.length - opti);
14141                 }
14142                 synchronized (this) {
14143                     if (dumpCheckinFormat) {
14144                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14145                                 dumpPackage);
14146                     } else {
14147                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14148                     }
14149                 }
14150             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14151                 String[] newArgs;
14152                 String name;
14153                 if (opti >= args.length) {
14154                     name = null;
14155                     newArgs = EMPTY_STRING_ARRAY;
14156                 } else {
14157                     dumpPackage = args[opti];
14158                     opti++;
14159                     newArgs = new String[args.length - opti];
14160                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14161                             args.length - opti);
14162                 }
14163                 synchronized (this) {
14164                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14165                 }
14166             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14167                 String[] newArgs;
14168                 String name;
14169                 if (opti >= args.length) {
14170                     name = null;
14171                     newArgs = EMPTY_STRING_ARRAY;
14172                 } else {
14173                     dumpPackage = args[opti];
14174                     opti++;
14175                     newArgs = new String[args.length - opti];
14176                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14177                             args.length - opti);
14178                 }
14179                 synchronized (this) {
14180                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14181                 }
14182             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14183                 synchronized (this) {
14184                     dumpOomLocked(fd, pw, args, opti, true);
14185                 }
14186             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14187                 synchronized (this) {
14188                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
14189                 }
14190             } else if ("provider".equals(cmd)) {
14191                 String[] newArgs;
14192                 String name;
14193                 if (opti >= args.length) {
14194                     name = null;
14195                     newArgs = EMPTY_STRING_ARRAY;
14196                 } else {
14197                     name = args[opti];
14198                     opti++;
14199                     newArgs = new String[args.length - opti];
14200                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14201                 }
14202                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14203                     pw.println("No providers match: " + name);
14204                     pw.println("Use -h for help.");
14205                 }
14206             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14207                 synchronized (this) {
14208                     dumpProvidersLocked(fd, pw, args, opti, true, null);
14209                 }
14210             } else if ("service".equals(cmd)) {
14211                 String[] newArgs;
14212                 String name;
14213                 if (opti >= args.length) {
14214                     name = null;
14215                     newArgs = EMPTY_STRING_ARRAY;
14216                 } else {
14217                     name = args[opti];
14218                     opti++;
14219                     newArgs = new String[args.length - opti];
14220                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14221                             args.length - opti);
14222                 }
14223                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14224                     pw.println("No services match: " + name);
14225                     pw.println("Use -h for help.");
14226                 }
14227             } else if ("package".equals(cmd)) {
14228                 String[] newArgs;
14229                 if (opti >= args.length) {
14230                     pw.println("package: no package name specified");
14231                     pw.println("Use -h for help.");
14232                 } else {
14233                     dumpPackage = args[opti];
14234                     opti++;
14235                     newArgs = new String[args.length - opti];
14236                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14237                             args.length - opti);
14238                     args = newArgs;
14239                     opti = 0;
14240                     more = true;
14241                 }
14242             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14243                 synchronized (this) {
14244                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14245                 }
14246             } else if ("services".equals(cmd) || "s".equals(cmd)) {
14247                 if (dumpClient) {
14248                     ActiveServices.ServiceDumper dumper;
14249                     synchronized (this) {
14250                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14251                                 dumpPackage);
14252                     }
14253                     dumper.dumpWithClient();
14254                 } else {
14255                     synchronized (this) {
14256                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14257                                 dumpPackage).dumpLocked();
14258                     }
14259                 }
14260             } else if ("locks".equals(cmd)) {
14261                 LockGuard.dump(fd, pw, args);
14262             } else {
14263                 // Dumping a single activity?
14264                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14265                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14266                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14267                     if (res < 0) {
14268                         pw.println("Bad activity command, or no activities match: " + cmd);
14269                         pw.println("Use -h for help.");
14270                     }
14271                 }
14272             }
14273             if (!more) {
14274                 Binder.restoreCallingIdentity(origId);
14275                 return;
14276             }
14277         }
14278 
14279         // No piece of data specified, dump everything.
14280         if (dumpCheckinFormat) {
14281             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14282         } else if (dumpClient) {
14283             ActiveServices.ServiceDumper sdumper;
14284             synchronized (this) {
14285                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14286                 pw.println();
14287                 if (dumpAll) {
14288                     pw.println("-------------------------------------------------------------------------------");
14289                 }
14290                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14291                 pw.println();
14292                 if (dumpAll) {
14293                     pw.println("-------------------------------------------------------------------------------");
14294                 }
14295                 if (dumpAll || dumpPackage != null) {
14296                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14297                     pw.println();
14298                     if (dumpAll) {
14299                         pw.println("-------------------------------------------------------------------------------");
14300                     }
14301                 }
14302                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14303                 pw.println();
14304                 if (dumpAll) {
14305                     pw.println("-------------------------------------------------------------------------------");
14306                 }
14307                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14308                 pw.println();
14309                 if (dumpAll) {
14310                     pw.println("-------------------------------------------------------------------------------");
14311                 }
14312                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14313                         dumpPackage);
14314             }
14315             sdumper.dumpWithClient();
14316             pw.println();
14317             synchronized (this) {
14318                 if (dumpAll) {
14319                     pw.println("-------------------------------------------------------------------------------");
14320                 }
14321                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14322                 pw.println();
14323                 if (dumpAll) {
14324                     pw.println("-------------------------------------------------------------------------------");
14325                 }
14326                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14327                 if (mAssociations.size() > 0) {
14328                     pw.println();
14329                     if (dumpAll) {
14330                         pw.println("-------------------------------------------------------------------------------");
14331                     }
14332                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14333                 }
14334                 pw.println();
14335                 if (dumpAll) {
14336                     pw.println("-------------------------------------------------------------------------------");
14337                 }
14338                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14339             }
14340 
14341         } else {
14342             synchronized (this) {
14343                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14344                 pw.println();
14345                 if (dumpAll) {
14346                     pw.println("-------------------------------------------------------------------------------");
14347                 }
14348                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14349                 pw.println();
14350                 if (dumpAll) {
14351                     pw.println("-------------------------------------------------------------------------------");
14352                 }
14353                 if (dumpAll || dumpPackage != null) {
14354                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14355                     pw.println();
14356                     if (dumpAll) {
14357                         pw.println("-------------------------------------------------------------------------------");
14358                     }
14359                 }
14360                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14361                 pw.println();
14362                 if (dumpAll) {
14363                     pw.println("-------------------------------------------------------------------------------");
14364                 }
14365                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14366                 pw.println();
14367                 if (dumpAll) {
14368                     pw.println("-------------------------------------------------------------------------------");
14369                 }
14370                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14371                         .dumpLocked();
14372                 pw.println();
14373                 if (dumpAll) {
14374                     pw.println("-------------------------------------------------------------------------------");
14375                 }
14376                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14377                 pw.println();
14378                 if (dumpAll) {
14379                     pw.println("-------------------------------------------------------------------------------");
14380                 }
14381                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14382                 if (mAssociations.size() > 0) {
14383                     pw.println();
14384                     if (dumpAll) {
14385                         pw.println("-------------------------------------------------------------------------------");
14386                     }
14387                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14388                 }
14389                 pw.println();
14390                 if (dumpAll) {
14391                     pw.println("-------------------------------------------------------------------------------");
14392                 }
14393                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14394             }
14395         }
14396         Binder.restoreCallingIdentity(origId);
14397     }
14398 
dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage)14399     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14400             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14401         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14402 
14403         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14404                 dumpPackage);
14405         boolean needSep = printedAnything;
14406 
14407         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14408                 dumpPackage, needSep, "  mFocusedActivity: ");
14409         if (printed) {
14410             printedAnything = true;
14411             needSep = false;
14412         }
14413 
14414         if (dumpPackage == null) {
14415             if (needSep) {
14416                 pw.println();
14417             }
14418             needSep = true;
14419             printedAnything = true;
14420             mStackSupervisor.dump(pw, "  ");
14421         }
14422 
14423         if (!printedAnything) {
14424             pw.println("  (nothing)");
14425         }
14426     }
14427 
dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)14428     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14429             int opti, boolean dumpAll, String dumpPackage) {
14430         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14431 
14432         boolean printedAnything = false;
14433 
14434         if (mRecentTasks != null && mRecentTasks.size() > 0) {
14435             boolean printedHeader = false;
14436 
14437             final int N = mRecentTasks.size();
14438             for (int i=0; i<N; i++) {
14439                 TaskRecord tr = mRecentTasks.get(i);
14440                 if (dumpPackage != null) {
14441                     if (tr.realActivity == null ||
14442                             !dumpPackage.equals(tr.realActivity)) {
14443                         continue;
14444                     }
14445                 }
14446                 if (!printedHeader) {
14447                     pw.println("  Recent tasks:");
14448                     printedHeader = true;
14449                     printedAnything = true;
14450                 }
14451                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14452                         pw.println(tr);
14453                 if (dumpAll) {
14454                     mRecentTasks.get(i).dump(pw, "    ");
14455                 }
14456             }
14457         }
14458 
14459         if (!printedAnything) {
14460             pw.println("  (nothing)");
14461         }
14462     }
14463 
dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, boolean dumpClient, String dumpPackage)14464     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14465             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14466         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14467 
14468         int dumpUid = 0;
14469         if (dumpPackage != null) {
14470             IPackageManager pm = AppGlobals.getPackageManager();
14471             try {
14472                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14473             } catch (RemoteException e) {
14474             }
14475         }
14476 
14477         boolean printedAnything = false;
14478 
14479         final long now = SystemClock.uptimeMillis();
14480 
14481         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14482             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14483                     = mAssociations.valueAt(i1);
14484             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14485                 SparseArray<ArrayMap<String, Association>> sourceUids
14486                         = targetComponents.valueAt(i2);
14487                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14488                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14489                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14490                         Association ass = sourceProcesses.valueAt(i4);
14491                         if (dumpPackage != null) {
14492                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14493                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14494                                 continue;
14495                             }
14496                         }
14497                         printedAnything = true;
14498                         pw.print("  ");
14499                         pw.print(ass.mTargetProcess);
14500                         pw.print("/");
14501                         UserHandle.formatUid(pw, ass.mTargetUid);
14502                         pw.print(" <- ");
14503                         pw.print(ass.mSourceProcess);
14504                         pw.print("/");
14505                         UserHandle.formatUid(pw, ass.mSourceUid);
14506                         pw.println();
14507                         pw.print("    via ");
14508                         pw.print(ass.mTargetComponent.flattenToShortString());
14509                         pw.println();
14510                         pw.print("    ");
14511                         long dur = ass.mTime;
14512                         if (ass.mNesting > 0) {
14513                             dur += now - ass.mStartTime;
14514                         }
14515                         TimeUtils.formatDuration(dur, pw);
14516                         pw.print(" (");
14517                         pw.print(ass.mCount);
14518                         pw.print(" times)");
14519                         pw.print("  ");
14520                         for (int i=0; i<ass.mStateTimes.length; i++) {
14521                             long amt = ass.mStateTimes[i];
14522                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14523                                 amt += now - ass.mLastStateUptime;
14524                             }
14525                             if (amt != 0) {
14526                                 pw.print(" ");
14527                                 pw.print(ProcessList.makeProcStateString(
14528                                             i + ActivityManager.MIN_PROCESS_STATE));
14529                                 pw.print("=");
14530                                 TimeUtils.formatDuration(amt, pw);
14531                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14532                                     pw.print("*");
14533                                 }
14534                             }
14535                         }
14536                         pw.println();
14537                         if (ass.mNesting > 0) {
14538                             pw.print("    Currently active: ");
14539                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
14540                             pw.println();
14541                         }
14542                     }
14543                 }
14544             }
14545 
14546         }
14547 
14548         if (!printedAnything) {
14549             pw.println("  (nothing)");
14550         }
14551     }
14552 
dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids, String header, boolean needSep)14553     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14554             String header, boolean needSep) {
14555         boolean printed = false;
14556         int whichAppId = -1;
14557         if (dumpPackage != null) {
14558             try {
14559                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14560                         dumpPackage, 0);
14561                 whichAppId = UserHandle.getAppId(info.uid);
14562             } catch (NameNotFoundException e) {
14563                 e.printStackTrace();
14564             }
14565         }
14566         for (int i=0; i<uids.size(); i++) {
14567             UidRecord uidRec = uids.valueAt(i);
14568             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14569                 continue;
14570             }
14571             if (!printed) {
14572                 printed = true;
14573                 if (needSep) {
14574                     pw.println();
14575                 }
14576                 pw.print("  ");
14577                 pw.println(header);
14578                 needSep = true;
14579             }
14580             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14581             pw.print(": "); pw.println(uidRec);
14582         }
14583         return printed;
14584     }
14585 
dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)14586     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14587             int opti, boolean dumpAll, String dumpPackage) {
14588         boolean needSep = false;
14589         boolean printedAnything = false;
14590         int numPers = 0;
14591 
14592         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14593 
14594         if (dumpAll) {
14595             final int NP = mProcessNames.getMap().size();
14596             for (int ip=0; ip<NP; ip++) {
14597                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14598                 final int NA = procs.size();
14599                 for (int ia=0; ia<NA; ia++) {
14600                     ProcessRecord r = procs.valueAt(ia);
14601                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14602                         continue;
14603                     }
14604                     if (!needSep) {
14605                         pw.println("  All known processes:");
14606                         needSep = true;
14607                         printedAnything = true;
14608                     }
14609                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14610                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14611                         pw.print(" "); pw.println(r);
14612                     r.dump(pw, "    ");
14613                     if (r.persistent) {
14614                         numPers++;
14615                     }
14616                 }
14617             }
14618         }
14619 
14620         if (mIsolatedProcesses.size() > 0) {
14621             boolean printed = false;
14622             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14623                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14624                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14625                     continue;
14626                 }
14627                 if (!printed) {
14628                     if (needSep) {
14629                         pw.println();
14630                     }
14631                     pw.println("  Isolated process list (sorted by uid):");
14632                     printedAnything = true;
14633                     printed = true;
14634                     needSep = true;
14635                 }
14636                 pw.println(String.format("%sIsolated #%2d: %s",
14637                         "    ", i, r.toString()));
14638             }
14639         }
14640 
14641         if (mActiveUids.size() > 0) {
14642             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14643                 printedAnything = needSep = true;
14644             }
14645         }
14646         if (mValidateUids.size() > 0) {
14647             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14648                 printedAnything = needSep = true;
14649             }
14650         }
14651 
14652         if (mLruProcesses.size() > 0) {
14653             if (needSep) {
14654                 pw.println();
14655             }
14656             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14657                     pw.print(" total, non-act at ");
14658                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14659                     pw.print(", non-svc at ");
14660                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14661                     pw.println("):");
14662             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14663             needSep = true;
14664             printedAnything = true;
14665         }
14666 
14667         if (dumpAll || dumpPackage != null) {
14668             synchronized (mPidsSelfLocked) {
14669                 boolean printed = false;
14670                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14671                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14672                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14673                         continue;
14674                     }
14675                     if (!printed) {
14676                         if (needSep) pw.println();
14677                         needSep = true;
14678                         pw.println("  PID mappings:");
14679                         printed = true;
14680                         printedAnything = true;
14681                     }
14682                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14683                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14684                 }
14685             }
14686         }
14687 
14688         if (mForegroundProcesses.size() > 0) {
14689             synchronized (mPidsSelfLocked) {
14690                 boolean printed = false;
14691                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14692                     ProcessRecord r = mPidsSelfLocked.get(
14693                             mForegroundProcesses.valueAt(i).pid);
14694                     if (dumpPackage != null && (r == null
14695                             || !r.pkgList.containsKey(dumpPackage))) {
14696                         continue;
14697                     }
14698                     if (!printed) {
14699                         if (needSep) pw.println();
14700                         needSep = true;
14701                         pw.println("  Foreground Processes:");
14702                         printed = true;
14703                         printedAnything = true;
14704                     }
14705                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14706                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14707                 }
14708             }
14709         }
14710 
14711         if (mPersistentStartingProcesses.size() > 0) {
14712             if (needSep) pw.println();
14713             needSep = true;
14714             printedAnything = true;
14715             pw.println("  Persisent processes that are starting:");
14716             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14717                     "Starting Norm", "Restarting PERS", dumpPackage);
14718         }
14719 
14720         if (mRemovedProcesses.size() > 0) {
14721             if (needSep) pw.println();
14722             needSep = true;
14723             printedAnything = true;
14724             pw.println("  Processes that are being removed:");
14725             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14726                     "Removed Norm", "Removed PERS", dumpPackage);
14727         }
14728 
14729         if (mProcessesOnHold.size() > 0) {
14730             if (needSep) pw.println();
14731             needSep = true;
14732             printedAnything = true;
14733             pw.println("  Processes that are on old until the system is ready:");
14734             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14735                     "OnHold Norm", "OnHold PERS", dumpPackage);
14736         }
14737 
14738         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14739 
14740         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14741         if (needSep) {
14742             printedAnything = true;
14743         }
14744 
14745         if (dumpPackage == null) {
14746             pw.println();
14747             needSep = false;
14748             mUserController.dump(pw, dumpAll);
14749         }
14750         if (mHomeProcess != null && (dumpPackage == null
14751                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14752             if (needSep) {
14753                 pw.println();
14754                 needSep = false;
14755             }
14756             pw.println("  mHomeProcess: " + mHomeProcess);
14757         }
14758         if (mPreviousProcess != null && (dumpPackage == null
14759                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14760             if (needSep) {
14761                 pw.println();
14762                 needSep = false;
14763             }
14764             pw.println("  mPreviousProcess: " + mPreviousProcess);
14765         }
14766         if (dumpAll) {
14767             StringBuilder sb = new StringBuilder(128);
14768             sb.append("  mPreviousProcessVisibleTime: ");
14769             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14770             pw.println(sb);
14771         }
14772         if (mHeavyWeightProcess != null && (dumpPackage == null
14773                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14774             if (needSep) {
14775                 pw.println();
14776                 needSep = false;
14777             }
14778             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14779         }
14780         if (dumpPackage == null) {
14781             pw.println("  mConfiguration: " + mConfiguration);
14782         }
14783         if (dumpAll) {
14784             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14785             if (mCompatModePackages.getPackages().size() > 0) {
14786                 boolean printed = false;
14787                 for (Map.Entry<String, Integer> entry
14788                         : mCompatModePackages.getPackages().entrySet()) {
14789                     String pkg = entry.getKey();
14790                     int mode = entry.getValue();
14791                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14792                         continue;
14793                     }
14794                     if (!printed) {
14795                         pw.println("  mScreenCompatPackages:");
14796                         printed = true;
14797                     }
14798                     pw.print("    "); pw.print(pkg); pw.print(": ");
14799                             pw.print(mode); pw.println();
14800                 }
14801             }
14802         }
14803         if (dumpPackage == null) {
14804             pw.println("  mWakefulness="
14805                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14806             pw.println("  mSleepTokens=" + mSleepTokens);
14807             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14808                     + lockScreenShownToString());
14809             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14810             if (mRunningVoice != null) {
14811                 pw.println("  mRunningVoice=" + mRunningVoice);
14812                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14813             }
14814         }
14815         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14816                 || mOrigWaitForDebugger) {
14817             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14818                     || dumpPackage.equals(mOrigDebugApp)) {
14819                 if (needSep) {
14820                     pw.println();
14821                     needSep = false;
14822                 }
14823                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14824                         + " mDebugTransient=" + mDebugTransient
14825                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14826             }
14827         }
14828         if (mCurAppTimeTracker != null) {
14829             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14830         }
14831         if (mMemWatchProcesses.getMap().size() > 0) {
14832             pw.println("  Mem watch processes:");
14833             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14834                     = mMemWatchProcesses.getMap();
14835             for (int i=0; i<procs.size(); i++) {
14836                 final String proc = procs.keyAt(i);
14837                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14838                 for (int j=0; j<uids.size(); j++) {
14839                     if (needSep) {
14840                         pw.println();
14841                         needSep = false;
14842                     }
14843                     StringBuilder sb = new StringBuilder();
14844                     sb.append("    ").append(proc).append('/');
14845                     UserHandle.formatUid(sb, uids.keyAt(j));
14846                     Pair<Long, String> val = uids.valueAt(j);
14847                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14848                     if (val.second != null) {
14849                         sb.append(", report to ").append(val.second);
14850                     }
14851                     pw.println(sb.toString());
14852                 }
14853             }
14854             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14855             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14856             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14857                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14858         }
14859         if (mTrackAllocationApp != null) {
14860             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14861                 if (needSep) {
14862                     pw.println();
14863                     needSep = false;
14864                 }
14865                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14866             }
14867         }
14868         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14869                 || mProfileFd != null) {
14870             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14871                 if (needSep) {
14872                     pw.println();
14873                     needSep = false;
14874                 }
14875                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14876                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14877                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14878                         + mAutoStopProfiler);
14879                 pw.println("  mProfileType=" + mProfileType);
14880             }
14881         }
14882         if (mNativeDebuggingApp != null) {
14883             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14884                 if (needSep) {
14885                     pw.println();
14886                     needSep = false;
14887                 }
14888                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14889             }
14890         }
14891         if (dumpPackage == null) {
14892             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14893                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14894                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14895             }
14896             if (mController != null) {
14897                 pw.println("  mController=" + mController
14898                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14899             }
14900             if (dumpAll) {
14901                 pw.println("  Total persistent processes: " + numPers);
14902                 pw.println("  mProcessesReady=" + mProcessesReady
14903                         + " mSystemReady=" + mSystemReady
14904                         + " mBooted=" + mBooted
14905                         + " mFactoryTest=" + mFactoryTest);
14906                 pw.println("  mBooting=" + mBooting
14907                         + " mCallFinishBooting=" + mCallFinishBooting
14908                         + " mBootAnimationComplete=" + mBootAnimationComplete);
14909                 pw.print("  mLastPowerCheckRealtime=");
14910                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14911                         pw.println("");
14912                 pw.print("  mLastPowerCheckUptime=");
14913                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14914                         pw.println("");
14915                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14916                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14917                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14918                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14919                         + " (" + mLruProcesses.size() + " total)"
14920                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14921                         + " mNumServiceProcs=" + mNumServiceProcs
14922                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14923                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14924                         + " mLastMemoryLevel=" + mLastMemoryLevel
14925                         + " mLastNumProcesses=" + mLastNumProcesses);
14926                 long now = SystemClock.uptimeMillis();
14927                 pw.print("  mLastIdleTime=");
14928                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
14929                         pw.print(" mLowRamSinceLastIdle=");
14930                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
14931                         pw.println();
14932             }
14933         }
14934 
14935         if (!printedAnything) {
14936             pw.println("  (nothing)");
14937         }
14938     }
14939 
dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean needSep, boolean dumpAll, String dumpPackage)14940     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
14941             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
14942         if (mProcessesToGc.size() > 0) {
14943             boolean printed = false;
14944             long now = SystemClock.uptimeMillis();
14945             for (int i=0; i<mProcessesToGc.size(); i++) {
14946                 ProcessRecord proc = mProcessesToGc.get(i);
14947                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
14948                     continue;
14949                 }
14950                 if (!printed) {
14951                     if (needSep) pw.println();
14952                     needSep = true;
14953                     pw.println("  Processes that are waiting to GC:");
14954                     printed = true;
14955                 }
14956                 pw.print("    Process "); pw.println(proc);
14957                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
14958                         pw.print(", last gced=");
14959                         pw.print(now-proc.lastRequestedGc);
14960                         pw.print(" ms ago, last lowMem=");
14961                         pw.print(now-proc.lastLowMemory);
14962                         pw.println(" ms ago");
14963 
14964             }
14965         }
14966         return needSep;
14967     }
14968 
printOomLevel(PrintWriter pw, String name, int adj)14969     void printOomLevel(PrintWriter pw, String name, int adj) {
14970         pw.print("    ");
14971         if (adj >= 0) {
14972             pw.print(' ');
14973             if (adj < 10) pw.print(' ');
14974         } else {
14975             if (adj > -10) pw.print(' ');
14976         }
14977         pw.print(adj);
14978         pw.print(": ");
14979         pw.print(name);
14980         pw.print(" (");
14981         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
14982         pw.println(")");
14983     }
14984 
dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll)14985     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14986             int opti, boolean dumpAll) {
14987         boolean needSep = false;
14988 
14989         if (mLruProcesses.size() > 0) {
14990             if (needSep) pw.println();
14991             needSep = true;
14992             pw.println("  OOM levels:");
14993             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
14994             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
14995             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
14996             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
14997             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
14998             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
14999             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15000             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15001             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15002             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15003             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15004             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15005             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15006             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15007 
15008             if (needSep) pw.println();
15009             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15010                     pw.print(" total, non-act at ");
15011                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15012                     pw.print(", non-svc at ");
15013                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15014                     pw.println("):");
15015             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15016             needSep = true;
15017         }
15018 
15019         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15020 
15021         pw.println();
15022         pw.println("  mHomeProcess: " + mHomeProcess);
15023         pw.println("  mPreviousProcess: " + mPreviousProcess);
15024         if (mHeavyWeightProcess != null) {
15025             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15026         }
15027 
15028         return true;
15029     }
15030 
15031     /**
15032      * There are three ways to call this:
15033      *  - no provider specified: dump all the providers
15034      *  - a flattened component name that matched an existing provider was specified as the
15035      *    first arg: dump that one provider
15036      *  - the first arg isn't the flattened component name of an existing provider:
15037      *    dump all providers whose component contains the first arg as a substring
15038      */
dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)15039     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15040             int opti, boolean dumpAll) {
15041         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15042     }
15043 
15044     static class ItemMatcher {
15045         ArrayList<ComponentName> components;
15046         ArrayList<String> strings;
15047         ArrayList<Integer> objects;
15048         boolean all;
15049 
ItemMatcher()15050         ItemMatcher() {
15051             all = true;
15052         }
15053 
build(String name)15054         void build(String name) {
15055             ComponentName componentName = ComponentName.unflattenFromString(name);
15056             if (componentName != null) {
15057                 if (components == null) {
15058                     components = new ArrayList<ComponentName>();
15059                 }
15060                 components.add(componentName);
15061                 all = false;
15062             } else {
15063                 int objectId = 0;
15064                 // Not a '/' separated full component name; maybe an object ID?
15065                 try {
15066                     objectId = Integer.parseInt(name, 16);
15067                     if (objects == null) {
15068                         objects = new ArrayList<Integer>();
15069                     }
15070                     objects.add(objectId);
15071                     all = false;
15072                 } catch (RuntimeException e) {
15073                     // Not an integer; just do string match.
15074                     if (strings == null) {
15075                         strings = new ArrayList<String>();
15076                     }
15077                     strings.add(name);
15078                     all = false;
15079                 }
15080             }
15081         }
15082 
build(String[] args, int opti)15083         int build(String[] args, int opti) {
15084             for (; opti<args.length; opti++) {
15085                 String name = args[opti];
15086                 if ("--".equals(name)) {
15087                     return opti+1;
15088                 }
15089                 build(name);
15090             }
15091             return opti;
15092         }
15093 
match(Object object, ComponentName comp)15094         boolean match(Object object, ComponentName comp) {
15095             if (all) {
15096                 return true;
15097             }
15098             if (components != null) {
15099                 for (int i=0; i<components.size(); i++) {
15100                     if (components.get(i).equals(comp)) {
15101                         return true;
15102                     }
15103                 }
15104             }
15105             if (objects != null) {
15106                 for (int i=0; i<objects.size(); i++) {
15107                     if (System.identityHashCode(object) == objects.get(i)) {
15108                         return true;
15109                     }
15110                 }
15111             }
15112             if (strings != null) {
15113                 String flat = comp.flattenToString();
15114                 for (int i=0; i<strings.size(); i++) {
15115                     if (flat.contains(strings.get(i))) {
15116                         return true;
15117                     }
15118                 }
15119             }
15120             return false;
15121         }
15122     }
15123 
15124     /**
15125      * There are three things that cmd can be:
15126      *  - a flattened component name that matches an existing activity
15127      *  - the cmd arg isn't the flattened component name of an existing activity:
15128      *    dump all activity whose component contains the cmd as a substring
15129      *  - A hex number of the ActivityRecord object instance.
15130      */
dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args, int opti, boolean dumpAll)15131     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15132             int opti, boolean dumpAll) {
15133         ArrayList<ActivityRecord> activities;
15134 
15135         synchronized (this) {
15136             activities = mStackSupervisor.getDumpActivitiesLocked(name);
15137         }
15138 
15139         if (activities.size() <= 0) {
15140             return false;
15141         }
15142 
15143         String[] newArgs = new String[args.length - opti];
15144         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15145 
15146         TaskRecord lastTask = null;
15147         boolean needSep = false;
15148         for (int i=activities.size()-1; i>=0; i--) {
15149             ActivityRecord r = activities.get(i);
15150             if (needSep) {
15151                 pw.println();
15152             }
15153             needSep = true;
15154             synchronized (this) {
15155                 if (lastTask != r.task) {
15156                     lastTask = r.task;
15157                     pw.print("TASK "); pw.print(lastTask.affinity);
15158                             pw.print(" id="); pw.println(lastTask.taskId);
15159                     if (dumpAll) {
15160                         lastTask.dump(pw, "  ");
15161                     }
15162                 }
15163             }
15164             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15165         }
15166         return true;
15167     }
15168 
15169     /**
15170      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15171      * there is a thread associated with the activity.
15172      */
dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw, final ActivityRecord r, String[] args, boolean dumpAll)15173     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15174             final ActivityRecord r, String[] args, boolean dumpAll) {
15175         String innerPrefix = prefix + "  ";
15176         synchronized (this) {
15177             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15178                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15179                     pw.print(" pid=");
15180                     if (r.app != null) pw.println(r.app.pid);
15181                     else pw.println("(not running)");
15182             if (dumpAll) {
15183                 r.dump(pw, innerPrefix);
15184             }
15185         }
15186         if (r.app != null && r.app.thread != null) {
15187             // flush anything that is already in the PrintWriter since the thread is going
15188             // to write to the file descriptor directly
15189             pw.flush();
15190             try {
15191                 TransferPipe tp = new TransferPipe();
15192                 try {
15193                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15194                             r.appToken, innerPrefix, args);
15195                     tp.go(fd);
15196                 } finally {
15197                     tp.kill();
15198                 }
15199             } catch (IOException e) {
15200                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15201             } catch (RemoteException e) {
15202                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15203             }
15204         }
15205     }
15206 
dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)15207     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15208             int opti, boolean dumpAll, String dumpPackage) {
15209         boolean needSep = false;
15210         boolean onlyHistory = false;
15211         boolean printedAnything = false;
15212 
15213         if ("history".equals(dumpPackage)) {
15214             if (opti < args.length && "-s".equals(args[opti])) {
15215                 dumpAll = false;
15216             }
15217             onlyHistory = true;
15218             dumpPackage = null;
15219         }
15220 
15221         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15222         if (!onlyHistory && dumpAll) {
15223             if (mRegisteredReceivers.size() > 0) {
15224                 boolean printed = false;
15225                 Iterator it = mRegisteredReceivers.values().iterator();
15226                 while (it.hasNext()) {
15227                     ReceiverList r = (ReceiverList)it.next();
15228                     if (dumpPackage != null && (r.app == null ||
15229                             !dumpPackage.equals(r.app.info.packageName))) {
15230                         continue;
15231                     }
15232                     if (!printed) {
15233                         pw.println("  Registered Receivers:");
15234                         needSep = true;
15235                         printed = true;
15236                         printedAnything = true;
15237                     }
15238                     pw.print("  * "); pw.println(r);
15239                     r.dump(pw, "    ");
15240                 }
15241             }
15242 
15243             if (mReceiverResolver.dump(pw, needSep ?
15244                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15245                     "    ", dumpPackage, false, false)) {
15246                 needSep = true;
15247                 printedAnything = true;
15248             }
15249         }
15250 
15251         for (BroadcastQueue q : mBroadcastQueues) {
15252             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15253             printedAnything |= needSep;
15254         }
15255 
15256         needSep = true;
15257 
15258         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15259             for (int user=0; user<mStickyBroadcasts.size(); user++) {
15260                 if (needSep) {
15261                     pw.println();
15262                 }
15263                 needSep = true;
15264                 printedAnything = true;
15265                 pw.print("  Sticky broadcasts for user ");
15266                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15267                 StringBuilder sb = new StringBuilder(128);
15268                 for (Map.Entry<String, ArrayList<Intent>> ent
15269                         : mStickyBroadcasts.valueAt(user).entrySet()) {
15270                     pw.print("  * Sticky action "); pw.print(ent.getKey());
15271                     if (dumpAll) {
15272                         pw.println(":");
15273                         ArrayList<Intent> intents = ent.getValue();
15274                         final int N = intents.size();
15275                         for (int i=0; i<N; i++) {
15276                             sb.setLength(0);
15277                             sb.append("    Intent: ");
15278                             intents.get(i).toShortString(sb, false, true, false, false);
15279                             pw.println(sb.toString());
15280                             Bundle bundle = intents.get(i).getExtras();
15281                             if (bundle != null) {
15282                                 pw.print("      ");
15283                                 pw.println(bundle.toString());
15284                             }
15285                         }
15286                     } else {
15287                         pw.println("");
15288                     }
15289                 }
15290             }
15291         }
15292 
15293         if (!onlyHistory && dumpAll) {
15294             pw.println();
15295             for (BroadcastQueue queue : mBroadcastQueues) {
15296                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15297                         + queue.mBroadcastsScheduled);
15298             }
15299             pw.println("  mHandler:");
15300             mHandler.dump(new PrintWriterPrinter(pw), "    ");
15301             needSep = true;
15302             printedAnything = true;
15303         }
15304 
15305         if (!printedAnything) {
15306             pw.println("  (nothing)");
15307         }
15308     }
15309 
dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)15310     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15311             int opti, boolean dumpAll, String dumpPackage) {
15312         if (mCurBroadcastStats == null) {
15313             return;
15314         }
15315 
15316         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15317         final long now = SystemClock.elapsedRealtime();
15318         if (mLastBroadcastStats != null) {
15319             pw.print("  Last stats (from ");
15320             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15321             pw.print(" to ");
15322             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15323             pw.print(", ");
15324             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15325                     - mLastBroadcastStats.mStartUptime, pw);
15326             pw.println(" uptime):");
15327             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15328                 pw.println("    (nothing)");
15329             }
15330             pw.println();
15331         }
15332         pw.print("  Current stats (from ");
15333         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15334         pw.print(" to now, ");
15335         TimeUtils.formatDuration(SystemClock.uptimeMillis()
15336                 - mCurBroadcastStats.mStartUptime, pw);
15337         pw.println(" uptime):");
15338         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15339             pw.println("    (nothing)");
15340         }
15341     }
15342 
dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean fullCheckin, String dumpPackage)15343     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15344             int opti, boolean fullCheckin, String dumpPackage) {
15345         if (mCurBroadcastStats == null) {
15346             return;
15347         }
15348 
15349         if (mLastBroadcastStats != null) {
15350             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15351             if (fullCheckin) {
15352                 mLastBroadcastStats = null;
15353                 return;
15354             }
15355         }
15356         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15357         if (fullCheckin) {
15358             mCurBroadcastStats = null;
15359         }
15360     }
15361 
dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)15362     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15363             int opti, boolean dumpAll, String dumpPackage) {
15364         boolean needSep;
15365         boolean printedAnything = false;
15366 
15367         ItemMatcher matcher = new ItemMatcher();
15368         matcher.build(args, opti);
15369 
15370         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15371 
15372         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15373         printedAnything |= needSep;
15374 
15375         if (mLaunchingProviders.size() > 0) {
15376             boolean printed = false;
15377             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15378                 ContentProviderRecord r = mLaunchingProviders.get(i);
15379                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15380                     continue;
15381                 }
15382                 if (!printed) {
15383                     if (needSep) pw.println();
15384                     needSep = true;
15385                     pw.println("  Launching content providers:");
15386                     printed = true;
15387                     printedAnything = true;
15388                 }
15389                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
15390                         pw.println(r);
15391             }
15392         }
15393 
15394         if (!printedAnything) {
15395             pw.println("  (nothing)");
15396         }
15397     }
15398 
dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)15399     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15400             int opti, boolean dumpAll, String dumpPackage) {
15401         boolean needSep = false;
15402         boolean printedAnything = false;
15403 
15404         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15405 
15406         if (mGrantedUriPermissions.size() > 0) {
15407             boolean printed = false;
15408             int dumpUid = -2;
15409             if (dumpPackage != null) {
15410                 try {
15411                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15412                             MATCH_UNINSTALLED_PACKAGES, 0);
15413                 } catch (NameNotFoundException e) {
15414                     dumpUid = -1;
15415                 }
15416             }
15417             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15418                 int uid = mGrantedUriPermissions.keyAt(i);
15419                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15420                     continue;
15421                 }
15422                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15423                 if (!printed) {
15424                     if (needSep) pw.println();
15425                     needSep = true;
15426                     pw.println("  Granted Uri Permissions:");
15427                     printed = true;
15428                     printedAnything = true;
15429                 }
15430                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15431                 for (UriPermission perm : perms.values()) {
15432                     pw.print("    "); pw.println(perm);
15433                     if (dumpAll) {
15434                         perm.dump(pw, "      ");
15435                     }
15436                 }
15437             }
15438         }
15439 
15440         if (!printedAnything) {
15441             pw.println("  (nothing)");
15442         }
15443     }
15444 
dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args, int opti, boolean dumpAll, String dumpPackage)15445     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15446             int opti, boolean dumpAll, String dumpPackage) {
15447         boolean printed = false;
15448 
15449         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15450 
15451         if (mIntentSenderRecords.size() > 0) {
15452             Iterator<WeakReference<PendingIntentRecord>> it
15453                     = mIntentSenderRecords.values().iterator();
15454             while (it.hasNext()) {
15455                 WeakReference<PendingIntentRecord> ref = it.next();
15456                 PendingIntentRecord rec = ref != null ? ref.get(): null;
15457                 if (dumpPackage != null && (rec == null
15458                         || !dumpPackage.equals(rec.key.packageName))) {
15459                     continue;
15460                 }
15461                 printed = true;
15462                 if (rec != null) {
15463                     pw.print("  * "); pw.println(rec);
15464                     if (dumpAll) {
15465                         rec.dump(pw, "    ");
15466                     }
15467                 } else {
15468                     pw.print("  * "); pw.println(ref);
15469                 }
15470             }
15471         }
15472 
15473         if (!printed) {
15474             pw.println("  (nothing)");
15475         }
15476     }
15477 
dumpProcessList(PrintWriter pw, ActivityManagerService service, List list, String prefix, String normalLabel, String persistentLabel, String dumpPackage)15478     private static final int dumpProcessList(PrintWriter pw,
15479             ActivityManagerService service, List list,
15480             String prefix, String normalLabel, String persistentLabel,
15481             String dumpPackage) {
15482         int numPers = 0;
15483         final int N = list.size()-1;
15484         for (int i=N; i>=0; i--) {
15485             ProcessRecord r = (ProcessRecord)list.get(i);
15486             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15487                 continue;
15488             }
15489             pw.println(String.format("%s%s #%2d: %s",
15490                     prefix, (r.persistent ? persistentLabel : normalLabel),
15491                     i, r.toString()));
15492             if (r.persistent) {
15493                 numPers++;
15494             }
15495         }
15496         return numPers;
15497     }
15498 
dumpProcessOomList(PrintWriter pw, ActivityManagerService service, List<ProcessRecord> origList, String prefix, String normalLabel, String persistentLabel, boolean inclDetails, String dumpPackage)15499     private static final boolean dumpProcessOomList(PrintWriter pw,
15500             ActivityManagerService service, List<ProcessRecord> origList,
15501             String prefix, String normalLabel, String persistentLabel,
15502             boolean inclDetails, String dumpPackage) {
15503 
15504         ArrayList<Pair<ProcessRecord, Integer>> list
15505                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15506         for (int i=0; i<origList.size(); i++) {
15507             ProcessRecord r = origList.get(i);
15508             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15509                 continue;
15510             }
15511             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15512         }
15513 
15514         if (list.size() <= 0) {
15515             return false;
15516         }
15517 
15518         Comparator<Pair<ProcessRecord, Integer>> comparator
15519                 = new Comparator<Pair<ProcessRecord, Integer>>() {
15520             @Override
15521             public int compare(Pair<ProcessRecord, Integer> object1,
15522                     Pair<ProcessRecord, Integer> object2) {
15523                 if (object1.first.setAdj != object2.first.setAdj) {
15524                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15525                 }
15526                 if (object1.first.setProcState != object2.first.setProcState) {
15527                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15528                 }
15529                 if (object1.second.intValue() != object2.second.intValue()) {
15530                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15531                 }
15532                 return 0;
15533             }
15534         };
15535 
15536         Collections.sort(list, comparator);
15537 
15538         final long curRealtime = SystemClock.elapsedRealtime();
15539         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15540         final long curUptime = SystemClock.uptimeMillis();
15541         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15542 
15543         for (int i=list.size()-1; i>=0; i--) {
15544             ProcessRecord r = list.get(i).first;
15545             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15546             char schedGroup;
15547             switch (r.setSchedGroup) {
15548                 case ProcessList.SCHED_GROUP_BACKGROUND:
15549                     schedGroup = 'B';
15550                     break;
15551                 case ProcessList.SCHED_GROUP_DEFAULT:
15552                     schedGroup = 'F';
15553                     break;
15554                 case ProcessList.SCHED_GROUP_TOP_APP:
15555                     schedGroup = 'T';
15556                     break;
15557                 default:
15558                     schedGroup = '?';
15559                     break;
15560             }
15561             char foreground;
15562             if (r.foregroundActivities) {
15563                 foreground = 'A';
15564             } else if (r.foregroundServices) {
15565                 foreground = 'S';
15566             } else {
15567                 foreground = ' ';
15568             }
15569             String procState = ProcessList.makeProcStateString(r.curProcState);
15570             pw.print(prefix);
15571             pw.print(r.persistent ? persistentLabel : normalLabel);
15572             pw.print(" #");
15573             int num = (origList.size()-1)-list.get(i).second;
15574             if (num < 10) pw.print(' ');
15575             pw.print(num);
15576             pw.print(": ");
15577             pw.print(oomAdj);
15578             pw.print(' ');
15579             pw.print(schedGroup);
15580             pw.print('/');
15581             pw.print(foreground);
15582             pw.print('/');
15583             pw.print(procState);
15584             pw.print(" trm:");
15585             if (r.trimMemoryLevel < 10) pw.print(' ');
15586             pw.print(r.trimMemoryLevel);
15587             pw.print(' ');
15588             pw.print(r.toShortString());
15589             pw.print(" (");
15590             pw.print(r.adjType);
15591             pw.println(')');
15592             if (r.adjSource != null || r.adjTarget != null) {
15593                 pw.print(prefix);
15594                 pw.print("    ");
15595                 if (r.adjTarget instanceof ComponentName) {
15596                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15597                 } else if (r.adjTarget != null) {
15598                     pw.print(r.adjTarget.toString());
15599                 } else {
15600                     pw.print("{null}");
15601                 }
15602                 pw.print("<=");
15603                 if (r.adjSource instanceof ProcessRecord) {
15604                     pw.print("Proc{");
15605                     pw.print(((ProcessRecord)r.adjSource).toShortString());
15606                     pw.println("}");
15607                 } else if (r.adjSource != null) {
15608                     pw.println(r.adjSource.toString());
15609                 } else {
15610                     pw.println("{null}");
15611                 }
15612             }
15613             if (inclDetails) {
15614                 pw.print(prefix);
15615                 pw.print("    ");
15616                 pw.print("oom: max="); pw.print(r.maxAdj);
15617                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15618                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15619                 pw.print(" cur="); pw.print(r.curAdj);
15620                 pw.print(" set="); pw.println(r.setAdj);
15621                 pw.print(prefix);
15622                 pw.print("    ");
15623                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15624                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15625                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15626                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15627                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15628                 pw.println();
15629                 pw.print(prefix);
15630                 pw.print("    ");
15631                 pw.print("cached="); pw.print(r.cached);
15632                 pw.print(" empty="); pw.print(r.empty);
15633                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15634 
15635                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15636                     if (r.lastWakeTime != 0) {
15637                         long wtime;
15638                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15639                         synchronized (stats) {
15640                             wtime = stats.getProcessWakeTime(r.info.uid,
15641                                     r.pid, curRealtime);
15642                         }
15643                         long timeUsed = wtime - r.lastWakeTime;
15644                         pw.print(prefix);
15645                         pw.print("    ");
15646                         pw.print("keep awake over ");
15647                         TimeUtils.formatDuration(realtimeSince, pw);
15648                         pw.print(" used ");
15649                         TimeUtils.formatDuration(timeUsed, pw);
15650                         pw.print(" (");
15651                         pw.print((timeUsed*100)/realtimeSince);
15652                         pw.println("%)");
15653                     }
15654                     if (r.lastCpuTime != 0) {
15655                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15656                         pw.print(prefix);
15657                         pw.print("    ");
15658                         pw.print("run cpu over ");
15659                         TimeUtils.formatDuration(uptimeSince, pw);
15660                         pw.print(" used ");
15661                         TimeUtils.formatDuration(timeUsed, pw);
15662                         pw.print(" (");
15663                         pw.print((timeUsed*100)/uptimeSince);
15664                         pw.println("%)");
15665                     }
15666                 }
15667             }
15668         }
15669         return true;
15670     }
15671 
collectProcesses(PrintWriter pw, int start, boolean allPkgs, String[] args)15672     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15673             String[] args) {
15674         ArrayList<ProcessRecord> procs;
15675         synchronized (this) {
15676             if (args != null && args.length > start
15677                     && args[start].charAt(0) != '-') {
15678                 procs = new ArrayList<ProcessRecord>();
15679                 int pid = -1;
15680                 try {
15681                     pid = Integer.parseInt(args[start]);
15682                 } catch (NumberFormatException e) {
15683                 }
15684                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15685                     ProcessRecord proc = mLruProcesses.get(i);
15686                     if (proc.pid == pid) {
15687                         procs.add(proc);
15688                     } else if (allPkgs && proc.pkgList != null
15689                             && proc.pkgList.containsKey(args[start])) {
15690                         procs.add(proc);
15691                     } else if (proc.processName.equals(args[start])) {
15692                         procs.add(proc);
15693                     }
15694                 }
15695                 if (procs.size() <= 0) {
15696                     return null;
15697                 }
15698             } else {
15699                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15700             }
15701         }
15702         return procs;
15703     }
15704 
dumpGraphicsHardwareUsage(FileDescriptor fd, PrintWriter pw, String[] args)15705     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15706             PrintWriter pw, String[] args) {
15707         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15708         if (procs == null) {
15709             pw.println("No process found for: " + args[0]);
15710             return;
15711         }
15712 
15713         long uptime = SystemClock.uptimeMillis();
15714         long realtime = SystemClock.elapsedRealtime();
15715         pw.println("Applications Graphics Acceleration Info:");
15716         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15717 
15718         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15719             ProcessRecord r = procs.get(i);
15720             if (r.thread != null) {
15721                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15722                 pw.flush();
15723                 try {
15724                     TransferPipe tp = new TransferPipe();
15725                     try {
15726                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15727                         tp.go(fd);
15728                     } finally {
15729                         tp.kill();
15730                     }
15731                 } catch (IOException e) {
15732                     pw.println("Failure while dumping the app: " + r);
15733                     pw.flush();
15734                 } catch (RemoteException e) {
15735                     pw.println("Got a RemoteException while dumping the app " + r);
15736                     pw.flush();
15737                 }
15738             }
15739         }
15740     }
15741 
dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args)15742     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15743         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15744         if (procs == null) {
15745             pw.println("No process found for: " + args[0]);
15746             return;
15747         }
15748 
15749         pw.println("Applications Database Info:");
15750 
15751         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15752             ProcessRecord r = procs.get(i);
15753             if (r.thread != null) {
15754                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15755                 pw.flush();
15756                 try {
15757                     TransferPipe tp = new TransferPipe();
15758                     try {
15759                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15760                         tp.go(fd);
15761                     } finally {
15762                         tp.kill();
15763                     }
15764                 } catch (IOException e) {
15765                     pw.println("Failure while dumping the app: " + r);
15766                     pw.flush();
15767                 } catch (RemoteException e) {
15768                     pw.println("Got a RemoteException while dumping the app " + r);
15769                     pw.flush();
15770                 }
15771             }
15772         }
15773     }
15774 
15775     final static class MemItem {
15776         final boolean isProc;
15777         final String label;
15778         final String shortLabel;
15779         final long pss;
15780         final long swapPss;
15781         final int id;
15782         final boolean hasActivities;
15783         ArrayList<MemItem> subitems;
15784 
MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id, boolean _hasActivities)15785         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15786                 boolean _hasActivities) {
15787             isProc = true;
15788             label = _label;
15789             shortLabel = _shortLabel;
15790             pss = _pss;
15791             swapPss = _swapPss;
15792             id = _id;
15793             hasActivities = _hasActivities;
15794         }
15795 
MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id)15796         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15797             isProc = false;
15798             label = _label;
15799             shortLabel = _shortLabel;
15800             pss = _pss;
15801             swapPss = _swapPss;
15802             id = _id;
15803             hasActivities = false;
15804         }
15805     }
15806 
dumpMemItems(PrintWriter pw, String prefix, String tag, ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss)15807     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15808             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15809         if (sort && !isCompact) {
15810             Collections.sort(items, new Comparator<MemItem>() {
15811                 @Override
15812                 public int compare(MemItem lhs, MemItem rhs) {
15813                     if (lhs.pss < rhs.pss) {
15814                         return 1;
15815                     } else if (lhs.pss > rhs.pss) {
15816                         return -1;
15817                     }
15818                     return 0;
15819                 }
15820             });
15821         }
15822 
15823         for (int i=0; i<items.size(); i++) {
15824             MemItem mi = items.get(i);
15825             if (!isCompact) {
15826                 if (dumpSwapPss) {
15827                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15828                             mi.label, stringifyKBSize(mi.swapPss));
15829                 } else {
15830                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15831                 }
15832             } else if (mi.isProc) {
15833                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15834                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15835                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15836                 pw.println(mi.hasActivities ? ",a" : ",e");
15837             } else {
15838                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15839                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15840             }
15841             if (mi.subitems != null) {
15842                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15843                         true, isCompact, dumpSwapPss);
15844             }
15845         }
15846     }
15847 
15848     // These are in KB.
15849     static final long[] DUMP_MEM_BUCKETS = new long[] {
15850         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15851         120*1024, 160*1024, 200*1024,
15852         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15853         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15854     };
15855 
appendMemBucket(StringBuilder out, long memKB, String label, boolean stackLike)15856     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15857             boolean stackLike) {
15858         int start = label.lastIndexOf('.');
15859         if (start >= 0) start++;
15860         else start = 0;
15861         int end = label.length();
15862         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15863             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15864                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15865                 out.append(bucket);
15866                 out.append(stackLike ? "MB." : "MB ");
15867                 out.append(label, start, end);
15868                 return;
15869             }
15870         }
15871         out.append(memKB/1024);
15872         out.append(stackLike ? "MB." : "MB ");
15873         out.append(label, start, end);
15874     }
15875 
15876     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15877             ProcessList.NATIVE_ADJ,
15878             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15879             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15880             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15881             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15882             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15883             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15884     };
15885     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15886             "Native",
15887             "System", "Persistent", "Persistent Service", "Foreground",
15888             "Visible", "Perceptible",
15889             "Heavy Weight", "Backup",
15890             "A Services", "Home",
15891             "Previous", "B Services", "Cached"
15892     };
15893     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15894             "native",
15895             "sys", "pers", "persvc", "fore",
15896             "vis", "percept",
15897             "heavy", "backup",
15898             "servicea", "home",
15899             "prev", "serviceb", "cached"
15900     };
15901 
dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime, long realtime, boolean isCheckinRequest, boolean isCompact)15902     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15903             long realtime, boolean isCheckinRequest, boolean isCompact) {
15904         if (isCompact) {
15905             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15906         }
15907         if (isCheckinRequest || isCompact) {
15908             // short checkin version
15909             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15910         } else {
15911             pw.println("Applications Memory Usage (in Kilobytes):");
15912             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15913         }
15914     }
15915 
15916     private static final int KSM_SHARED = 0;
15917     private static final int KSM_SHARING = 1;
15918     private static final int KSM_UNSHARED = 2;
15919     private static final int KSM_VOLATILE = 3;
15920 
getKsmInfo()15921     private final long[] getKsmInfo() {
15922         long[] longOut = new long[4];
15923         final int[] SINGLE_LONG_FORMAT = new int[] {
15924             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15925         };
15926         long[] longTmp = new long[1];
15927         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
15928                 SINGLE_LONG_FORMAT, null, longTmp, null);
15929         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15930         longTmp[0] = 0;
15931         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
15932                 SINGLE_LONG_FORMAT, null, longTmp, null);
15933         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15934         longTmp[0] = 0;
15935         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
15936                 SINGLE_LONG_FORMAT, null, longTmp, null);
15937         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15938         longTmp[0] = 0;
15939         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
15940                 SINGLE_LONG_FORMAT, null, longTmp, null);
15941         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
15942         return longOut;
15943     }
15944 
stringifySize(long size, int order)15945     private static String stringifySize(long size, int order) {
15946         Locale locale = Locale.US;
15947         switch (order) {
15948             case 1:
15949                 return String.format(locale, "%,13d", size);
15950             case 1024:
15951                 return String.format(locale, "%,9dK", size / 1024);
15952             case 1024 * 1024:
15953                 return String.format(locale, "%,5dM", size / 1024 / 1024);
15954             case 1024 * 1024 * 1024:
15955                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
15956             default:
15957                 throw new IllegalArgumentException("Invalid size order");
15958         }
15959     }
15960 
stringifyKBSize(long size)15961     private static String stringifyKBSize(long size) {
15962         return stringifySize(size * 1024, 1024);
15963     }
15964 
15965     // Update this version number in case you change the 'compact' format
15966     private static final int MEMINFO_COMPACT_VERSION = 1;
15967 
dumpApplicationMemoryUsage(FileDescriptor fd, PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw)15968     final void dumpApplicationMemoryUsage(FileDescriptor fd,
15969             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
15970         boolean dumpDetails = false;
15971         boolean dumpFullDetails = false;
15972         boolean dumpDalvik = false;
15973         boolean dumpSummaryOnly = false;
15974         boolean dumpUnreachable = false;
15975         boolean oomOnly = false;
15976         boolean isCompact = false;
15977         boolean localOnly = false;
15978         boolean packages = false;
15979         boolean isCheckinRequest = false;
15980         boolean dumpSwapPss = false;
15981 
15982         int opti = 0;
15983         while (opti < args.length) {
15984             String opt = args[opti];
15985             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
15986                 break;
15987             }
15988             opti++;
15989             if ("-a".equals(opt)) {
15990                 dumpDetails = true;
15991                 dumpFullDetails = true;
15992                 dumpDalvik = true;
15993                 dumpSwapPss = true;
15994             } else if ("-d".equals(opt)) {
15995                 dumpDalvik = true;
15996             } else if ("-c".equals(opt)) {
15997                 isCompact = true;
15998             } else if ("-s".equals(opt)) {
15999                 dumpDetails = true;
16000                 dumpSummaryOnly = true;
16001             } else if ("-S".equals(opt)) {
16002                 dumpSwapPss = true;
16003             } else if ("--unreachable".equals(opt)) {
16004                 dumpUnreachable = true;
16005             } else if ("--oom".equals(opt)) {
16006                 oomOnly = true;
16007             } else if ("--local".equals(opt)) {
16008                 localOnly = true;
16009             } else if ("--package".equals(opt)) {
16010                 packages = true;
16011             } else if ("--checkin".equals(opt)) {
16012                 isCheckinRequest = true;
16013 
16014             } else if ("-h".equals(opt)) {
16015                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16016                 pw.println("  -a: include all available information for each process.");
16017                 pw.println("  -d: include dalvik details.");
16018                 pw.println("  -c: dump in a compact machine-parseable representation.");
16019                 pw.println("  -s: dump only summary of application memory usage.");
16020                 pw.println("  -S: dump also SwapPss.");
16021                 pw.println("  --oom: only show processes organized by oom adj.");
16022                 pw.println("  --local: only collect details locally, don't call process.");
16023                 pw.println("  --package: interpret process arg as package, dumping all");
16024                 pw.println("             processes that have loaded that package.");
16025                 pw.println("  --checkin: dump data for a checkin");
16026                 pw.println("If [process] is specified it can be the name or ");
16027                 pw.println("pid of a specific process to dump.");
16028                 return;
16029             } else {
16030                 pw.println("Unknown argument: " + opt + "; use -h for help");
16031             }
16032         }
16033 
16034         long uptime = SystemClock.uptimeMillis();
16035         long realtime = SystemClock.elapsedRealtime();
16036         final long[] tmpLong = new long[1];
16037 
16038         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16039         if (procs == null) {
16040             // No Java processes.  Maybe they want to print a native process.
16041             if (args != null && args.length > opti
16042                     && args[opti].charAt(0) != '-') {
16043                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16044                         = new ArrayList<ProcessCpuTracker.Stats>();
16045                 updateCpuStatsNow();
16046                 int findPid = -1;
16047                 try {
16048                     findPid = Integer.parseInt(args[opti]);
16049                 } catch (NumberFormatException e) {
16050                 }
16051                 synchronized (mProcessCpuTracker) {
16052                     final int N = mProcessCpuTracker.countStats();
16053                     for (int i=0; i<N; i++) {
16054                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16055                         if (st.pid == findPid || (st.baseName != null
16056                                 && st.baseName.equals(args[opti]))) {
16057                             nativeProcs.add(st);
16058                         }
16059                     }
16060                 }
16061                 if (nativeProcs.size() > 0) {
16062                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16063                             isCompact);
16064                     Debug.MemoryInfo mi = null;
16065                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16066                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16067                         final int pid = r.pid;
16068                         if (!isCheckinRequest && dumpDetails) {
16069                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16070                         }
16071                         if (mi == null) {
16072                             mi = new Debug.MemoryInfo();
16073                         }
16074                         if (dumpDetails || (!brief && !oomOnly)) {
16075                             Debug.getMemoryInfo(pid, mi);
16076                         } else {
16077                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16078                             mi.dalvikPrivateDirty = (int)tmpLong[0];
16079                         }
16080                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16081                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16082                         if (isCheckinRequest) {
16083                             pw.println();
16084                         }
16085                     }
16086                     return;
16087                 }
16088             }
16089             pw.println("No process found for: " + args[opti]);
16090             return;
16091         }
16092 
16093         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16094             dumpDetails = true;
16095         }
16096 
16097         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16098 
16099         String[] innerArgs = new String[args.length-opti];
16100         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16101 
16102         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16103         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16104         long nativePss = 0;
16105         long nativeSwapPss = 0;
16106         long dalvikPss = 0;
16107         long dalvikSwapPss = 0;
16108         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16109                 EmptyArray.LONG;
16110         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16111                 EmptyArray.LONG;
16112         long otherPss = 0;
16113         long otherSwapPss = 0;
16114         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16115         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16116 
16117         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16118         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16119         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16120                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16121 
16122         long totalPss = 0;
16123         long totalSwapPss = 0;
16124         long cachedPss = 0;
16125         long cachedSwapPss = 0;
16126         boolean hasSwapPss = false;
16127 
16128         Debug.MemoryInfo mi = null;
16129         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16130             final ProcessRecord r = procs.get(i);
16131             final IApplicationThread thread;
16132             final int pid;
16133             final int oomAdj;
16134             final boolean hasActivities;
16135             synchronized (this) {
16136                 thread = r.thread;
16137                 pid = r.pid;
16138                 oomAdj = r.getSetAdjWithServices();
16139                 hasActivities = r.activities.size() > 0;
16140             }
16141             if (thread != null) {
16142                 if (!isCheckinRequest && dumpDetails) {
16143                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16144                 }
16145                 if (mi == null) {
16146                     mi = new Debug.MemoryInfo();
16147                 }
16148                 if (dumpDetails || (!brief && !oomOnly)) {
16149                     Debug.getMemoryInfo(pid, mi);
16150                     hasSwapPss = mi.hasSwappedOutPss;
16151                 } else {
16152                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16153                     mi.dalvikPrivateDirty = (int)tmpLong[0];
16154                 }
16155                 if (dumpDetails) {
16156                     if (localOnly) {
16157                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16158                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16159                         if (isCheckinRequest) {
16160                             pw.println();
16161                         }
16162                     } else {
16163                         try {
16164                             pw.flush();
16165                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16166                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16167                         } catch (RemoteException e) {
16168                             if (!isCheckinRequest) {
16169                                 pw.println("Got RemoteException!");
16170                                 pw.flush();
16171                             }
16172                         }
16173                     }
16174                 }
16175 
16176                 final long myTotalPss = mi.getTotalPss();
16177                 final long myTotalUss = mi.getTotalUss();
16178                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16179 
16180                 synchronized (this) {
16181                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16182                         // Record this for posterity if the process has been stable.
16183                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16184                     }
16185                 }
16186 
16187                 if (!isCheckinRequest && mi != null) {
16188                     totalPss += myTotalPss;
16189                     totalSwapPss += myTotalSwapPss;
16190                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16191                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16192                             myTotalSwapPss, pid, hasActivities);
16193                     procMems.add(pssItem);
16194                     procMemsMap.put(pid, pssItem);
16195 
16196                     nativePss += mi.nativePss;
16197                     nativeSwapPss += mi.nativeSwappedOutPss;
16198                     dalvikPss += mi.dalvikPss;
16199                     dalvikSwapPss += mi.dalvikSwappedOutPss;
16200                     for (int j=0; j<dalvikSubitemPss.length; j++) {
16201                         dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16202                         dalvikSubitemSwapPss[j] +=
16203                                 mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16204                     }
16205                     otherPss += mi.otherPss;
16206                     otherSwapPss += mi.otherSwappedOutPss;
16207                     for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16208                         long mem = mi.getOtherPss(j);
16209                         miscPss[j] += mem;
16210                         otherPss -= mem;
16211                         mem = mi.getOtherSwappedOutPss(j);
16212                         miscSwapPss[j] += mem;
16213                         otherSwapPss -= mem;
16214                     }
16215 
16216                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16217                         cachedPss += myTotalPss;
16218                         cachedSwapPss += myTotalSwapPss;
16219                     }
16220 
16221                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16222                         if (oomIndex == (oomPss.length - 1)
16223                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16224                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16225                             oomPss[oomIndex] += myTotalPss;
16226                             oomSwapPss[oomIndex] += myTotalSwapPss;
16227                             if (oomProcs[oomIndex] == null) {
16228                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
16229                             }
16230                             oomProcs[oomIndex].add(pssItem);
16231                             break;
16232                         }
16233                     }
16234                 }
16235             }
16236         }
16237 
16238         long nativeProcTotalPss = 0;
16239 
16240         if (!isCheckinRequest && procs.size() > 1 && !packages) {
16241             // If we are showing aggregations, also look for native processes to
16242             // include so that our aggregations are more accurate.
16243             updateCpuStatsNow();
16244             mi = null;
16245             synchronized (mProcessCpuTracker) {
16246                 final int N = mProcessCpuTracker.countStats();
16247                 for (int i=0; i<N; i++) {
16248                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16249                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16250                         if (mi == null) {
16251                             mi = new Debug.MemoryInfo();
16252                         }
16253                         if (!brief && !oomOnly) {
16254                             Debug.getMemoryInfo(st.pid, mi);
16255                         } else {
16256                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16257                             mi.nativePrivateDirty = (int)tmpLong[0];
16258                         }
16259 
16260                         final long myTotalPss = mi.getTotalPss();
16261                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16262                         totalPss += myTotalPss;
16263                         nativeProcTotalPss += myTotalPss;
16264 
16265                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16266                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16267                         procMems.add(pssItem);
16268 
16269                         nativePss += mi.nativePss;
16270                         nativeSwapPss += mi.nativeSwappedOutPss;
16271                         dalvikPss += mi.dalvikPss;
16272                         dalvikSwapPss += mi.dalvikSwappedOutPss;
16273                         for (int j=0; j<dalvikSubitemPss.length; j++) {
16274                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16275                             dalvikSubitemSwapPss[j] +=
16276                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16277                         }
16278                         otherPss += mi.otherPss;
16279                         otherSwapPss += mi.otherSwappedOutPss;
16280                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16281                             long mem = mi.getOtherPss(j);
16282                             miscPss[j] += mem;
16283                             otherPss -= mem;
16284                             mem = mi.getOtherSwappedOutPss(j);
16285                             miscSwapPss[j] += mem;
16286                             otherSwapPss -= mem;
16287                         }
16288                         oomPss[0] += myTotalPss;
16289                         oomSwapPss[0] += myTotalSwapPss;
16290                         if (oomProcs[0] == null) {
16291                             oomProcs[0] = new ArrayList<MemItem>();
16292                         }
16293                         oomProcs[0].add(pssItem);
16294                     }
16295                 }
16296             }
16297 
16298             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16299 
16300             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16301             final MemItem dalvikItem =
16302                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16303             if (dalvikSubitemPss.length > 0) {
16304                 dalvikItem.subitems = new ArrayList<MemItem>();
16305                 for (int j=0; j<dalvikSubitemPss.length; j++) {
16306                     final String name = Debug.MemoryInfo.getOtherLabel(
16307                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
16308                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16309                                     dalvikSubitemSwapPss[j], j));
16310                 }
16311             }
16312             catMems.add(dalvikItem);
16313             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16314             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16315                 String label = Debug.MemoryInfo.getOtherLabel(j);
16316                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16317             }
16318 
16319             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16320             for (int j=0; j<oomPss.length; j++) {
16321                 if (oomPss[j] != 0) {
16322                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16323                             : DUMP_MEM_OOM_LABEL[j];
16324                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16325                             DUMP_MEM_OOM_ADJ[j]);
16326                     item.subitems = oomProcs[j];
16327                     oomMems.add(item);
16328                 }
16329             }
16330 
16331             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16332             if (!brief && !oomOnly && !isCompact) {
16333                 pw.println();
16334                 pw.println("Total PSS by process:");
16335                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16336                 pw.println();
16337             }
16338             if (!isCompact) {
16339                 pw.println("Total PSS by OOM adjustment:");
16340             }
16341             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16342             if (!brief && !oomOnly) {
16343                 PrintWriter out = categoryPw != null ? categoryPw : pw;
16344                 if (!isCompact) {
16345                     out.println();
16346                     out.println("Total PSS by category:");
16347                 }
16348                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16349             }
16350             if (!isCompact) {
16351                 pw.println();
16352             }
16353             MemInfoReader memInfo = new MemInfoReader();
16354             memInfo.readMemInfo();
16355             if (nativeProcTotalPss > 0) {
16356                 synchronized (this) {
16357                     final long cachedKb = memInfo.getCachedSizeKb();
16358                     final long freeKb = memInfo.getFreeSizeKb();
16359                     final long zramKb = memInfo.getZramTotalSizeKb();
16360                     final long kernelKb = memInfo.getKernelUsedSizeKb();
16361                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16362                             kernelKb*1024, nativeProcTotalPss*1024);
16363                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16364                             nativeProcTotalPss);
16365                 }
16366             }
16367             if (!brief) {
16368                 if (!isCompact) {
16369                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16370                     pw.print(" (status ");
16371                     switch (mLastMemoryLevel) {
16372                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16373                             pw.println("normal)");
16374                             break;
16375                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16376                             pw.println("moderate)");
16377                             break;
16378                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
16379                             pw.println("low)");
16380                             break;
16381                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16382                             pw.println("critical)");
16383                             break;
16384                         default:
16385                             pw.print(mLastMemoryLevel);
16386                             pw.println(")");
16387                             break;
16388                     }
16389                     pw.print(" Free RAM: ");
16390                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16391                             + memInfo.getFreeSizeKb()));
16392                     pw.print(" (");
16393                     pw.print(stringifyKBSize(cachedPss));
16394                     pw.print(" cached pss + ");
16395                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16396                     pw.print(" cached kernel + ");
16397                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16398                     pw.println(" free)");
16399                 } else {
16400                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16401                     pw.print(cachedPss + memInfo.getCachedSizeKb()
16402                             + memInfo.getFreeSizeKb()); pw.print(",");
16403                     pw.println(totalPss - cachedPss);
16404                 }
16405             }
16406             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16407                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16408                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16409             if (!isCompact) {
16410                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16411                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16412                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16413                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16414                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16415             } else {
16416                 pw.print("lostram,"); pw.println(lostRAM);
16417             }
16418             if (!brief) {
16419                 if (memInfo.getZramTotalSizeKb() != 0) {
16420                     if (!isCompact) {
16421                         pw.print("     ZRAM: ");
16422                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16423                                 pw.print(" physical used for ");
16424                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16425                                         - memInfo.getSwapFreeSizeKb()));
16426                                 pw.print(" in swap (");
16427                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16428                                 pw.println(" total swap)");
16429                     } else {
16430                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16431                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16432                                 pw.println(memInfo.getSwapFreeSizeKb());
16433                     }
16434                 }
16435                 final long[] ksm = getKsmInfo();
16436                 if (!isCompact) {
16437                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16438                             || ksm[KSM_VOLATILE] != 0) {
16439                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16440                                 pw.print(" saved from shared ");
16441                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16442                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16443                                 pw.print(" unshared; ");
16444                                 pw.print(stringifyKBSize(
16445                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
16446                     }
16447                     pw.print("   Tuning: ");
16448                     pw.print(ActivityManager.staticGetMemoryClass());
16449                     pw.print(" (large ");
16450                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16451                     pw.print("), oom ");
16452                     pw.print(stringifySize(
16453                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16454                     pw.print(", restore limit ");
16455                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16456                     if (ActivityManager.isLowRamDeviceStatic()) {
16457                         pw.print(" (low-ram)");
16458                     }
16459                     if (ActivityManager.isHighEndGfx()) {
16460                         pw.print(" (high-end-gfx)");
16461                     }
16462                     pw.println();
16463                 } else {
16464                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16465                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16466                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16467                     pw.print("tuning,");
16468                     pw.print(ActivityManager.staticGetMemoryClass());
16469                     pw.print(',');
16470                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16471                     pw.print(',');
16472                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16473                     if (ActivityManager.isLowRamDeviceStatic()) {
16474                         pw.print(",low-ram");
16475                     }
16476                     if (ActivityManager.isHighEndGfx()) {
16477                         pw.print(",high-end-gfx");
16478                     }
16479                     pw.println();
16480                 }
16481             }
16482         }
16483     }
16484 
appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss, long memtrack, String name)16485     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16486             long memtrack, String name) {
16487         sb.append("  ");
16488         sb.append(ProcessList.makeOomAdjString(oomAdj));
16489         sb.append(' ');
16490         sb.append(ProcessList.makeProcStateString(procState));
16491         sb.append(' ');
16492         ProcessList.appendRamKb(sb, pss);
16493         sb.append(": ");
16494         sb.append(name);
16495         if (memtrack > 0) {
16496             sb.append(" (");
16497             sb.append(stringifyKBSize(memtrack));
16498             sb.append(" memtrack)");
16499         }
16500     }
16501 
appendMemInfo(StringBuilder sb, ProcessMemInfo mi)16502     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16503         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16504         sb.append(" (pid ");
16505         sb.append(mi.pid);
16506         sb.append(") ");
16507         sb.append(mi.adjType);
16508         sb.append('\n');
16509         if (mi.adjReason != null) {
16510             sb.append("                      ");
16511             sb.append(mi.adjReason);
16512             sb.append('\n');
16513         }
16514     }
16515 
reportMemUsage(ArrayList<ProcessMemInfo> memInfos)16516     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16517         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16518         for (int i=0, N=memInfos.size(); i<N; i++) {
16519             ProcessMemInfo mi = memInfos.get(i);
16520             infoMap.put(mi.pid, mi);
16521         }
16522         updateCpuStatsNow();
16523         long[] memtrackTmp = new long[1];
16524         synchronized (mProcessCpuTracker) {
16525             final int N = mProcessCpuTracker.countStats();
16526             for (int i=0; i<N; i++) {
16527                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16528                 if (st.vsize > 0) {
16529                     long pss = Debug.getPss(st.pid, null, memtrackTmp);
16530                     if (pss > 0) {
16531                         if (infoMap.indexOfKey(st.pid) < 0) {
16532                             ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16533                                     ProcessList.NATIVE_ADJ, -1, "native", null);
16534                             mi.pss = pss;
16535                             mi.memtrack = memtrackTmp[0];
16536                             memInfos.add(mi);
16537                         }
16538                     }
16539                 }
16540             }
16541         }
16542 
16543         long totalPss = 0;
16544         long totalMemtrack = 0;
16545         for (int i=0, N=memInfos.size(); i<N; i++) {
16546             ProcessMemInfo mi = memInfos.get(i);
16547             if (mi.pss == 0) {
16548                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16549                 mi.memtrack = memtrackTmp[0];
16550             }
16551             totalPss += mi.pss;
16552             totalMemtrack += mi.memtrack;
16553         }
16554         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16555             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16556                 if (lhs.oomAdj != rhs.oomAdj) {
16557                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16558                 }
16559                 if (lhs.pss != rhs.pss) {
16560                     return lhs.pss < rhs.pss ? 1 : -1;
16561                 }
16562                 return 0;
16563             }
16564         });
16565 
16566         StringBuilder tag = new StringBuilder(128);
16567         StringBuilder stack = new StringBuilder(128);
16568         tag.append("Low on memory -- ");
16569         appendMemBucket(tag, totalPss, "total", false);
16570         appendMemBucket(stack, totalPss, "total", true);
16571 
16572         StringBuilder fullNativeBuilder = new StringBuilder(1024);
16573         StringBuilder shortNativeBuilder = new StringBuilder(1024);
16574         StringBuilder fullJavaBuilder = new StringBuilder(1024);
16575 
16576         boolean firstLine = true;
16577         int lastOomAdj = Integer.MIN_VALUE;
16578         long extraNativeRam = 0;
16579         long extraNativeMemtrack = 0;
16580         long cachedPss = 0;
16581         for (int i=0, N=memInfos.size(); i<N; i++) {
16582             ProcessMemInfo mi = memInfos.get(i);
16583 
16584             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16585                 cachedPss += mi.pss;
16586             }
16587 
16588             if (mi.oomAdj != ProcessList.NATIVE_ADJ
16589                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
16590                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
16591                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16592                 if (lastOomAdj != mi.oomAdj) {
16593                     lastOomAdj = mi.oomAdj;
16594                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16595                         tag.append(" / ");
16596                     }
16597                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16598                         if (firstLine) {
16599                             stack.append(":");
16600                             firstLine = false;
16601                         }
16602                         stack.append("\n\t at ");
16603                     } else {
16604                         stack.append("$");
16605                     }
16606                 } else {
16607                     tag.append(" ");
16608                     stack.append("$");
16609                 }
16610                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16611                     appendMemBucket(tag, mi.pss, mi.name, false);
16612                 }
16613                 appendMemBucket(stack, mi.pss, mi.name, true);
16614                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16615                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16616                     stack.append("(");
16617                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16618                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16619                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16620                             stack.append(":");
16621                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16622                         }
16623                     }
16624                     stack.append(")");
16625                 }
16626             }
16627 
16628             appendMemInfo(fullNativeBuilder, mi);
16629             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16630                 // The short form only has native processes that are >= 512K.
16631                 if (mi.pss >= 512) {
16632                     appendMemInfo(shortNativeBuilder, mi);
16633                 } else {
16634                     extraNativeRam += mi.pss;
16635                     extraNativeMemtrack += mi.memtrack;
16636                 }
16637             } else {
16638                 // Short form has all other details, but if we have collected RAM
16639                 // from smaller native processes let's dump a summary of that.
16640                 if (extraNativeRam > 0) {
16641                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16642                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16643                     shortNativeBuilder.append('\n');
16644                     extraNativeRam = 0;
16645                 }
16646                 appendMemInfo(fullJavaBuilder, mi);
16647             }
16648         }
16649 
16650         fullJavaBuilder.append("           ");
16651         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16652         fullJavaBuilder.append(": TOTAL");
16653         if (totalMemtrack > 0) {
16654             fullJavaBuilder.append(" (");
16655             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16656             fullJavaBuilder.append(" memtrack)");
16657         } else {
16658         }
16659         fullJavaBuilder.append("\n");
16660 
16661         MemInfoReader memInfo = new MemInfoReader();
16662         memInfo.readMemInfo();
16663         final long[] infos = memInfo.getRawInfo();
16664 
16665         StringBuilder memInfoBuilder = new StringBuilder(1024);
16666         Debug.getMemInfo(infos);
16667         memInfoBuilder.append("  MemInfo: ");
16668         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16669         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16670         memInfoBuilder.append(stringifyKBSize(
16671                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16672         memInfoBuilder.append(stringifyKBSize(
16673                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16674         memInfoBuilder.append(stringifyKBSize(
16675                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16676         memInfoBuilder.append("           ");
16677         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16678         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16679         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16680         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16681         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16682             memInfoBuilder.append("  ZRAM: ");
16683             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16684             memInfoBuilder.append(" RAM, ");
16685             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16686             memInfoBuilder.append(" swap total, ");
16687             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16688             memInfoBuilder.append(" swap free\n");
16689         }
16690         final long[] ksm = getKsmInfo();
16691         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16692                 || ksm[KSM_VOLATILE] != 0) {
16693             memInfoBuilder.append("  KSM: ");
16694             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16695             memInfoBuilder.append(" saved from shared ");
16696             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16697             memInfoBuilder.append("\n       ");
16698             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16699             memInfoBuilder.append(" unshared; ");
16700             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16701             memInfoBuilder.append(" volatile\n");
16702         }
16703         memInfoBuilder.append("  Free RAM: ");
16704         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16705                 + memInfo.getFreeSizeKb()));
16706         memInfoBuilder.append("\n");
16707         memInfoBuilder.append("  Used RAM: ");
16708         memInfoBuilder.append(stringifyKBSize(
16709                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16710         memInfoBuilder.append("\n");
16711         memInfoBuilder.append("  Lost RAM: ");
16712         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16713                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16714                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16715         memInfoBuilder.append("\n");
16716         Slog.i(TAG, "Low on memory:");
16717         Slog.i(TAG, shortNativeBuilder.toString());
16718         Slog.i(TAG, fullJavaBuilder.toString());
16719         Slog.i(TAG, memInfoBuilder.toString());
16720 
16721         StringBuilder dropBuilder = new StringBuilder(1024);
16722         /*
16723         StringWriter oomSw = new StringWriter();
16724         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16725         StringWriter catSw = new StringWriter();
16726         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16727         String[] emptyArgs = new String[] { };
16728         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16729         oomPw.flush();
16730         String oomString = oomSw.toString();
16731         */
16732         dropBuilder.append("Low on memory:");
16733         dropBuilder.append(stack);
16734         dropBuilder.append('\n');
16735         dropBuilder.append(fullNativeBuilder);
16736         dropBuilder.append(fullJavaBuilder);
16737         dropBuilder.append('\n');
16738         dropBuilder.append(memInfoBuilder);
16739         dropBuilder.append('\n');
16740         /*
16741         dropBuilder.append(oomString);
16742         dropBuilder.append('\n');
16743         */
16744         StringWriter catSw = new StringWriter();
16745         synchronized (ActivityManagerService.this) {
16746             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16747             String[] emptyArgs = new String[] { };
16748             catPw.println();
16749             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16750             catPw.println();
16751             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16752                     false, null).dumpLocked();
16753             catPw.println();
16754             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16755             catPw.flush();
16756         }
16757         dropBuilder.append(catSw.toString());
16758         addErrorToDropBox("lowmem", null, "system_server", null,
16759                 null, tag.toString(), dropBuilder.toString(), null, null);
16760         //Slog.i(TAG, "Sent to dropbox:");
16761         //Slog.i(TAG, dropBuilder.toString());
16762         synchronized (ActivityManagerService.this) {
16763             long now = SystemClock.uptimeMillis();
16764             if (mLastMemUsageReportTime < now) {
16765                 mLastMemUsageReportTime = now;
16766             }
16767         }
16768     }
16769 
16770     /**
16771      * Searches array of arguments for the specified string
16772      * @param args array of argument strings
16773      * @param value value to search for
16774      * @return true if the value is contained in the array
16775      */
scanArgs(String[] args, String value)16776     private static boolean scanArgs(String[] args, String value) {
16777         if (args != null) {
16778             for (String arg : args) {
16779                 if (value.equals(arg)) {
16780                     return true;
16781                 }
16782             }
16783         }
16784         return false;
16785     }
16786 
removeDyingProviderLocked(ProcessRecord proc, ContentProviderRecord cpr, boolean always)16787     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16788             ContentProviderRecord cpr, boolean always) {
16789         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16790 
16791         if (!inLaunching || always) {
16792             synchronized (cpr) {
16793                 cpr.launchingApp = null;
16794                 cpr.notifyAll();
16795             }
16796             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16797             String names[] = cpr.info.authority.split(";");
16798             for (int j = 0; j < names.length; j++) {
16799                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16800             }
16801         }
16802 
16803         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16804             ContentProviderConnection conn = cpr.connections.get(i);
16805             if (conn.waiting) {
16806                 // If this connection is waiting for the provider, then we don't
16807                 // need to mess with its process unless we are always removing
16808                 // or for some reason the provider is not currently launching.
16809                 if (inLaunching && !always) {
16810                     continue;
16811                 }
16812             }
16813             ProcessRecord capp = conn.client;
16814             conn.dead = true;
16815             if (conn.stableCount > 0) {
16816                 if (!capp.persistent && capp.thread != null
16817                         && capp.pid != 0
16818                         && capp.pid != MY_PID) {
16819                     capp.kill("depends on provider "
16820                             + cpr.name.flattenToShortString()
16821                             + " in dying proc " + (proc != null ? proc.processName : "??")
16822                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16823                 }
16824             } else if (capp.thread != null && conn.provider.provider != null) {
16825                 try {
16826                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16827                 } catch (RemoteException e) {
16828                 }
16829                 // In the protocol here, we don't expect the client to correctly
16830                 // clean up this connection, we'll just remove it.
16831                 cpr.connections.remove(i);
16832                 if (conn.client.conProviders.remove(conn)) {
16833                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16834                 }
16835             }
16836         }
16837 
16838         if (inLaunching && always) {
16839             mLaunchingProviders.remove(cpr);
16840         }
16841         return inLaunching;
16842     }
16843 
16844     /**
16845      * Main code for cleaning up a process when it has gone away.  This is
16846      * called both as a result of the process dying, or directly when stopping
16847      * a process when running in single process mode.
16848      *
16849      * @return Returns true if the given process has been restarted, so the
16850      * app that was passed in must remain on the process lists.
16851      */
cleanUpApplicationRecordLocked(ProcessRecord app, boolean restarting, boolean allowRestart, int index, boolean replacingPid)16852     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16853             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16854         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16855         if (index >= 0) {
16856             removeLruProcessLocked(app);
16857             ProcessList.remove(app.pid);
16858         }
16859 
16860         mProcessesToGc.remove(app);
16861         mPendingPssProcesses.remove(app);
16862 
16863         // Dismiss any open dialogs.
16864         if (app.crashDialog != null && !app.forceCrashReport) {
16865             app.crashDialog.dismiss();
16866             app.crashDialog = null;
16867         }
16868         if (app.anrDialog != null) {
16869             app.anrDialog.dismiss();
16870             app.anrDialog = null;
16871         }
16872         if (app.waitDialog != null) {
16873             app.waitDialog.dismiss();
16874             app.waitDialog = null;
16875         }
16876 
16877         app.crashing = false;
16878         app.notResponding = false;
16879 
16880         app.resetPackageList(mProcessStats);
16881         app.unlinkDeathRecipient();
16882         app.makeInactive(mProcessStats);
16883         app.waitingToKill = null;
16884         app.forcingToForeground = null;
16885         updateProcessForegroundLocked(app, false, false);
16886         app.foregroundActivities = false;
16887         app.hasShownUi = false;
16888         app.treatLikeActivity = false;
16889         app.hasAboveClient = false;
16890         app.hasClientActivities = false;
16891 
16892         mServices.killServicesLocked(app, allowRestart);
16893 
16894         boolean restart = false;
16895 
16896         // Remove published content providers.
16897         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16898             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16899             final boolean always = app.bad || !allowRestart;
16900             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16901             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16902                 // We left the provider in the launching list, need to
16903                 // restart it.
16904                 restart = true;
16905             }
16906 
16907             cpr.provider = null;
16908             cpr.proc = null;
16909         }
16910         app.pubProviders.clear();
16911 
16912         // Take care of any launching providers waiting for this process.
16913         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16914             restart = true;
16915         }
16916 
16917         // Unregister from connected content providers.
16918         if (!app.conProviders.isEmpty()) {
16919             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16920                 ContentProviderConnection conn = app.conProviders.get(i);
16921                 conn.provider.connections.remove(conn);
16922                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16923                         conn.provider.name);
16924             }
16925             app.conProviders.clear();
16926         }
16927 
16928         // At this point there may be remaining entries in mLaunchingProviders
16929         // where we were the only one waiting, so they are no longer of use.
16930         // Look for these and clean up if found.
16931         // XXX Commented out for now.  Trying to figure out a way to reproduce
16932         // the actual situation to identify what is actually going on.
16933         if (false) {
16934             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
16935                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
16936                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
16937                     synchronized (cpr) {
16938                         cpr.launchingApp = null;
16939                         cpr.notifyAll();
16940                     }
16941                 }
16942             }
16943         }
16944 
16945         skipCurrentReceiverLocked(app);
16946 
16947         // Unregister any receivers.
16948         for (int i = app.receivers.size() - 1; i >= 0; i--) {
16949             removeReceiverLocked(app.receivers.valueAt(i));
16950         }
16951         app.receivers.clear();
16952 
16953         // If the app is undergoing backup, tell the backup manager about it
16954         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
16955             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
16956                     + mBackupTarget.appInfo + " died during backup");
16957             try {
16958                 IBackupManager bm = IBackupManager.Stub.asInterface(
16959                         ServiceManager.getService(Context.BACKUP_SERVICE));
16960                 bm.agentDisconnected(app.info.packageName);
16961             } catch (RemoteException e) {
16962                 // can't happen; backup manager is local
16963             }
16964         }
16965 
16966         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
16967             ProcessChangeItem item = mPendingProcessChanges.get(i);
16968             if (item.pid == app.pid) {
16969                 mPendingProcessChanges.remove(i);
16970                 mAvailProcessChanges.add(item);
16971             }
16972         }
16973         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
16974                 null).sendToTarget();
16975 
16976         // If the caller is restarting this app, then leave it in its
16977         // current lists and let the caller take care of it.
16978         if (restarting) {
16979             return false;
16980         }
16981 
16982         if (!app.persistent || app.isolated) {
16983             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
16984                     "Removing non-persistent process during cleanup: " + app);
16985             if (!replacingPid) {
16986                 removeProcessNameLocked(app.processName, app.uid);
16987             }
16988             if (mHeavyWeightProcess == app) {
16989                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
16990                         mHeavyWeightProcess.userId, 0));
16991                 mHeavyWeightProcess = null;
16992             }
16993         } else if (!app.removed) {
16994             // This app is persistent, so we need to keep its record around.
16995             // If it is not already on the pending app list, add it there
16996             // and start a new process for it.
16997             if (mPersistentStartingProcesses.indexOf(app) < 0) {
16998                 mPersistentStartingProcesses.add(app);
16999                 restart = true;
17000             }
17001         }
17002         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17003                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17004         mProcessesOnHold.remove(app);
17005 
17006         if (app == mHomeProcess) {
17007             mHomeProcess = null;
17008         }
17009         if (app == mPreviousProcess) {
17010             mPreviousProcess = null;
17011         }
17012 
17013         if (restart && !app.isolated) {
17014             // We have components that still need to be running in the
17015             // process, so re-launch it.
17016             if (index < 0) {
17017                 ProcessList.remove(app.pid);
17018             }
17019             addProcessNameLocked(app);
17020             startProcessLocked(app, "restart", app.processName);
17021             return true;
17022         } else if (app.pid > 0 && app.pid != MY_PID) {
17023             // Goodbye!
17024             boolean removed;
17025             synchronized (mPidsSelfLocked) {
17026                 mPidsSelfLocked.remove(app.pid);
17027                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17028             }
17029             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17030             if (app.isolated) {
17031                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17032             }
17033             app.setPid(0);
17034         }
17035         return false;
17036     }
17037 
checkAppInLaunchingProvidersLocked(ProcessRecord app)17038     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17039         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17040             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17041             if (cpr.launchingApp == app) {
17042                 return true;
17043             }
17044         }
17045         return false;
17046     }
17047 
cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad)17048     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17049         // Look through the content providers we are waiting to have launched,
17050         // and if any run in this process then either schedule a restart of
17051         // the process or kill the client waiting for it if this process has
17052         // gone bad.
17053         boolean restart = false;
17054         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17055             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17056             if (cpr.launchingApp == app) {
17057                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17058                     restart = true;
17059                 } else {
17060                     removeDyingProviderLocked(app, cpr, true);
17061                 }
17062             }
17063         }
17064         return restart;
17065     }
17066 
17067     // =========================================================
17068     // SERVICES
17069     // =========================================================
17070 
17071     @Override
getServices(int maxNum, int flags)17072     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17073             int flags) {
17074         enforceNotIsolatedCaller("getServices");
17075         synchronized (this) {
17076             return mServices.getRunningServiceInfoLocked(maxNum, flags);
17077         }
17078     }
17079 
17080     @Override
getRunningServiceControlPanel(ComponentName name)17081     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17082         enforceNotIsolatedCaller("getRunningServiceControlPanel");
17083         synchronized (this) {
17084             return mServices.getRunningServiceControlPanelLocked(name);
17085         }
17086     }
17087 
17088     @Override
startService(IApplicationThread caller, Intent service, String resolvedType, String callingPackage, int userId)17089     public ComponentName startService(IApplicationThread caller, Intent service,
17090             String resolvedType, String callingPackage, int userId)
17091             throws TransactionTooLargeException {
17092         enforceNotIsolatedCaller("startService");
17093         // Refuse possible leaked file descriptors
17094         if (service != null && service.hasFileDescriptors() == true) {
17095             throw new IllegalArgumentException("File descriptors passed in Intent");
17096         }
17097 
17098         if (callingPackage == null) {
17099             throw new IllegalArgumentException("callingPackage cannot be null");
17100         }
17101 
17102         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17103                 "startService: " + service + " type=" + resolvedType);
17104         synchronized(this) {
17105             final int callingPid = Binder.getCallingPid();
17106             final int callingUid = Binder.getCallingUid();
17107             final long origId = Binder.clearCallingIdentity();
17108             ComponentName res = mServices.startServiceLocked(caller, service,
17109                     resolvedType, callingPid, callingUid, callingPackage, userId);
17110             Binder.restoreCallingIdentity(origId);
17111             return res;
17112         }
17113     }
17114 
startServiceInPackage(int uid, Intent service, String resolvedType, String callingPackage, int userId)17115     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17116             String callingPackage, int userId)
17117             throws TransactionTooLargeException {
17118         synchronized(this) {
17119             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17120                     "startServiceInPackage: " + service + " type=" + resolvedType);
17121             final long origId = Binder.clearCallingIdentity();
17122             ComponentName res = mServices.startServiceLocked(null, service,
17123                     resolvedType, -1, uid, callingPackage, userId);
17124             Binder.restoreCallingIdentity(origId);
17125             return res;
17126         }
17127     }
17128 
17129     @Override
stopService(IApplicationThread caller, Intent service, String resolvedType, int userId)17130     public int stopService(IApplicationThread caller, Intent service,
17131             String resolvedType, int userId) {
17132         enforceNotIsolatedCaller("stopService");
17133         // Refuse possible leaked file descriptors
17134         if (service != null && service.hasFileDescriptors() == true) {
17135             throw new IllegalArgumentException("File descriptors passed in Intent");
17136         }
17137 
17138         synchronized(this) {
17139             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17140         }
17141     }
17142 
17143     @Override
peekService(Intent service, String resolvedType, String callingPackage)17144     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17145         enforceNotIsolatedCaller("peekService");
17146         // Refuse possible leaked file descriptors
17147         if (service != null && service.hasFileDescriptors() == true) {
17148             throw new IllegalArgumentException("File descriptors passed in Intent");
17149         }
17150 
17151         if (callingPackage == null) {
17152             throw new IllegalArgumentException("callingPackage cannot be null");
17153         }
17154 
17155         synchronized(this) {
17156             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17157         }
17158     }
17159 
17160     @Override
stopServiceToken(ComponentName className, IBinder token, int startId)17161     public boolean stopServiceToken(ComponentName className, IBinder token,
17162             int startId) {
17163         synchronized(this) {
17164             return mServices.stopServiceTokenLocked(className, token, startId);
17165         }
17166     }
17167 
17168     @Override
setServiceForeground(ComponentName className, IBinder token, int id, Notification notification, int flags)17169     public void setServiceForeground(ComponentName className, IBinder token,
17170             int id, Notification notification, int flags) {
17171         synchronized(this) {
17172             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17173         }
17174     }
17175 
17176     @Override
handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll, boolean requireFull, String name, String callerPackage)17177     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17178             boolean requireFull, String name, String callerPackage) {
17179         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17180                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17181     }
17182 
isSingleton(String componentProcessName, ApplicationInfo aInfo, String className, int flags)17183     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17184             String className, int flags) {
17185         boolean result = false;
17186         // For apps that don't have pre-defined UIDs, check for permission
17187         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17188             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17189                 if (ActivityManager.checkUidPermission(
17190                         INTERACT_ACROSS_USERS,
17191                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17192                     ComponentName comp = new ComponentName(aInfo.packageName, className);
17193                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
17194                             + " requests FLAG_SINGLE_USER, but app does not hold "
17195                             + INTERACT_ACROSS_USERS;
17196                     Slog.w(TAG, msg);
17197                     throw new SecurityException(msg);
17198                 }
17199                 // Permission passed
17200                 result = true;
17201             }
17202         } else if ("system".equals(componentProcessName)) {
17203             result = true;
17204         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17205             // Phone app and persistent apps are allowed to export singleuser providers.
17206             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17207                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17208         }
17209         if (DEBUG_MU) Slog.v(TAG_MU,
17210                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17211                 + Integer.toHexString(flags) + ") = " + result);
17212         return result;
17213     }
17214 
17215     /**
17216      * Checks to see if the caller is in the same app as the singleton
17217      * component, or the component is in a special app. It allows special apps
17218      * to export singleton components but prevents exporting singleton
17219      * components for regular apps.
17220      */
isValidSingletonCall(int callingUid, int componentUid)17221     boolean isValidSingletonCall(int callingUid, int componentUid) {
17222         int componentAppId = UserHandle.getAppId(componentUid);
17223         return UserHandle.isSameApp(callingUid, componentUid)
17224                 || componentAppId == Process.SYSTEM_UID
17225                 || componentAppId == Process.PHONE_UID
17226                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17227                         == PackageManager.PERMISSION_GRANTED;
17228     }
17229 
bindService(IApplicationThread caller, IBinder token, Intent service, String resolvedType, IServiceConnection connection, int flags, String callingPackage, int userId)17230     public int bindService(IApplicationThread caller, IBinder token, Intent service,
17231             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17232             int userId) throws TransactionTooLargeException {
17233         enforceNotIsolatedCaller("bindService");
17234 
17235         // Refuse possible leaked file descriptors
17236         if (service != null && service.hasFileDescriptors() == true) {
17237             throw new IllegalArgumentException("File descriptors passed in Intent");
17238         }
17239 
17240         if (callingPackage == null) {
17241             throw new IllegalArgumentException("callingPackage cannot be null");
17242         }
17243 
17244         synchronized(this) {
17245             return mServices.bindServiceLocked(caller, token, service,
17246                     resolvedType, connection, flags, callingPackage, userId);
17247         }
17248     }
17249 
unbindService(IServiceConnection connection)17250     public boolean unbindService(IServiceConnection connection) {
17251         synchronized (this) {
17252             return mServices.unbindServiceLocked(connection);
17253         }
17254     }
17255 
publishService(IBinder token, Intent intent, IBinder service)17256     public void publishService(IBinder token, Intent intent, IBinder service) {
17257         // Refuse possible leaked file descriptors
17258         if (intent != null && intent.hasFileDescriptors() == true) {
17259             throw new IllegalArgumentException("File descriptors passed in Intent");
17260         }
17261 
17262         synchronized(this) {
17263             if (!(token instanceof ServiceRecord)) {
17264                 throw new IllegalArgumentException("Invalid service token");
17265             }
17266             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17267         }
17268     }
17269 
unbindFinished(IBinder token, Intent intent, boolean doRebind)17270     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17271         // Refuse possible leaked file descriptors
17272         if (intent != null && intent.hasFileDescriptors() == true) {
17273             throw new IllegalArgumentException("File descriptors passed in Intent");
17274         }
17275 
17276         synchronized(this) {
17277             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17278         }
17279     }
17280 
serviceDoneExecuting(IBinder token, int type, int startId, int res)17281     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17282         synchronized(this) {
17283             if (!(token instanceof ServiceRecord)) {
17284                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17285                 throw new IllegalArgumentException("Invalid service token");
17286             }
17287             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17288         }
17289     }
17290 
17291     // =========================================================
17292     // BACKUP AND RESTORE
17293     // =========================================================
17294 
17295     // Cause the target app to be launched if necessary and its backup agent
17296     // instantiated.  The backup agent will invoke backupAgentCreated() on the
17297     // activity manager to announce its creation.
bindBackupAgent(String packageName, int backupMode, int userId)17298     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17299         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17300         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17301 
17302         IPackageManager pm = AppGlobals.getPackageManager();
17303         ApplicationInfo app = null;
17304         try {
17305             app = pm.getApplicationInfo(packageName, 0, userId);
17306         } catch (RemoteException e) {
17307             // can't happen; package manager is process-local
17308         }
17309         if (app == null) {
17310             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17311             return false;
17312         }
17313 
17314         synchronized(this) {
17315             // !!! TODO: currently no check here that we're already bound
17316             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17317             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17318             synchronized (stats) {
17319                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17320             }
17321 
17322             // Backup agent is now in use, its package can't be stopped.
17323             try {
17324                 AppGlobals.getPackageManager().setPackageStoppedState(
17325                         app.packageName, false, UserHandle.getUserId(app.uid));
17326             } catch (RemoteException e) {
17327             } catch (IllegalArgumentException e) {
17328                 Slog.w(TAG, "Failed trying to unstop package "
17329                         + app.packageName + ": " + e);
17330             }
17331 
17332             BackupRecord r = new BackupRecord(ss, app, backupMode);
17333             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17334                     ? new ComponentName(app.packageName, app.backupAgentName)
17335                     : new ComponentName("android", "FullBackupAgent");
17336             // startProcessLocked() returns existing proc's record if it's already running
17337             ProcessRecord proc = startProcessLocked(app.processName, app,
17338                     false, 0, "backup", hostingName, false, false, false);
17339             if (proc == null) {
17340                 Slog.e(TAG, "Unable to start backup agent process " + r);
17341                 return false;
17342             }
17343 
17344             // If the app is a regular app (uid >= 10000) and not the system server or phone
17345             // process, etc, then mark it as being in full backup so that certain calls to the
17346             // process can be blocked. This is not reset to false anywhere because we kill the
17347             // process after the full backup is done and the ProcessRecord will vaporize anyway.
17348             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17349                 proc.inFullBackup = true;
17350             }
17351             r.app = proc;
17352             mBackupTarget = r;
17353             mBackupAppName = app.packageName;
17354 
17355             // Try not to kill the process during backup
17356             updateOomAdjLocked(proc);
17357 
17358             // If the process is already attached, schedule the creation of the backup agent now.
17359             // If it is not yet live, this will be done when it attaches to the framework.
17360             if (proc.thread != null) {
17361                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17362                 try {
17363                     proc.thread.scheduleCreateBackupAgent(app,
17364                             compatibilityInfoForPackageLocked(app), backupMode);
17365                 } catch (RemoteException e) {
17366                     // Will time out on the backup manager side
17367                 }
17368             } else {
17369                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17370             }
17371             // Invariants: at this point, the target app process exists and the application
17372             // is either already running or in the process of coming up.  mBackupTarget and
17373             // mBackupAppName describe the app, so that when it binds back to the AM we
17374             // know that it's scheduled for a backup-agent operation.
17375         }
17376 
17377         return true;
17378     }
17379 
17380     @Override
clearPendingBackup()17381     public void clearPendingBackup() {
17382         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17383         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17384 
17385         synchronized (this) {
17386             mBackupTarget = null;
17387             mBackupAppName = null;
17388         }
17389     }
17390 
17391     // A backup agent has just come up
backupAgentCreated(String agentPackageName, IBinder agent)17392     public void backupAgentCreated(String agentPackageName, IBinder agent) {
17393         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17394                 + " = " + agent);
17395 
17396         synchronized(this) {
17397             if (!agentPackageName.equals(mBackupAppName)) {
17398                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17399                 return;
17400             }
17401         }
17402 
17403         long oldIdent = Binder.clearCallingIdentity();
17404         try {
17405             IBackupManager bm = IBackupManager.Stub.asInterface(
17406                     ServiceManager.getService(Context.BACKUP_SERVICE));
17407             bm.agentConnected(agentPackageName, agent);
17408         } catch (RemoteException e) {
17409             // can't happen; the backup manager service is local
17410         } catch (Exception e) {
17411             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17412             e.printStackTrace();
17413         } finally {
17414             Binder.restoreCallingIdentity(oldIdent);
17415         }
17416     }
17417 
17418     // done with this agent
unbindBackupAgent(ApplicationInfo appInfo)17419     public void unbindBackupAgent(ApplicationInfo appInfo) {
17420         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17421         if (appInfo == null) {
17422             Slog.w(TAG, "unbind backup agent for null app");
17423             return;
17424         }
17425 
17426         synchronized(this) {
17427             try {
17428                 if (mBackupAppName == null) {
17429                     Slog.w(TAG, "Unbinding backup agent with no active backup");
17430                     return;
17431                 }
17432 
17433                 if (!mBackupAppName.equals(appInfo.packageName)) {
17434                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17435                     return;
17436                 }
17437 
17438                 // Not backing this app up any more; reset its OOM adjustment
17439                 final ProcessRecord proc = mBackupTarget.app;
17440                 updateOomAdjLocked(proc);
17441 
17442                 // If the app crashed during backup, 'thread' will be null here
17443                 if (proc.thread != null) {
17444                     try {
17445                         proc.thread.scheduleDestroyBackupAgent(appInfo,
17446                                 compatibilityInfoForPackageLocked(appInfo));
17447                     } catch (Exception e) {
17448                         Slog.e(TAG, "Exception when unbinding backup agent:");
17449                         e.printStackTrace();
17450                     }
17451                 }
17452             } finally {
17453                 mBackupTarget = null;
17454                 mBackupAppName = null;
17455             }
17456         }
17457     }
17458     // =========================================================
17459     // BROADCASTS
17460     // =========================================================
17461 
isPendingBroadcastProcessLocked(int pid)17462     boolean isPendingBroadcastProcessLocked(int pid) {
17463         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17464                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17465     }
17466 
skipPendingBroadcastLocked(int pid)17467     void skipPendingBroadcastLocked(int pid) {
17468             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17469             for (BroadcastQueue queue : mBroadcastQueues) {
17470                 queue.skipPendingBroadcastLocked(pid);
17471             }
17472     }
17473 
17474     // The app just attached; send any pending broadcasts that it should receive
sendPendingBroadcastsLocked(ProcessRecord app)17475     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17476         boolean didSomething = false;
17477         for (BroadcastQueue queue : mBroadcastQueues) {
17478             didSomething |= queue.sendPendingBroadcastsLocked(app);
17479         }
17480         return didSomething;
17481     }
17482 
registerReceiver(IApplicationThread caller, String callerPackage, IIntentReceiver receiver, IntentFilter filter, String permission, int userId)17483     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17484             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17485         enforceNotIsolatedCaller("registerReceiver");
17486         ArrayList<Intent> stickyIntents = null;
17487         ProcessRecord callerApp = null;
17488         int callingUid;
17489         int callingPid;
17490         synchronized(this) {
17491             if (caller != null) {
17492                 callerApp = getRecordForAppLocked(caller);
17493                 if (callerApp == null) {
17494                     throw new SecurityException(
17495                             "Unable to find app for caller " + caller
17496                             + " (pid=" + Binder.getCallingPid()
17497                             + ") when registering receiver " + receiver);
17498                 }
17499                 if (callerApp.info.uid != Process.SYSTEM_UID &&
17500                         !callerApp.pkgList.containsKey(callerPackage) &&
17501                         !"android".equals(callerPackage)) {
17502                     throw new SecurityException("Given caller package " + callerPackage
17503                             + " is not running in process " + callerApp);
17504                 }
17505                 callingUid = callerApp.info.uid;
17506                 callingPid = callerApp.pid;
17507             } else {
17508                 callerPackage = null;
17509                 callingUid = Binder.getCallingUid();
17510                 callingPid = Binder.getCallingPid();
17511             }
17512 
17513             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17514                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17515 
17516             Iterator<String> actions = filter.actionsIterator();
17517             if (actions == null) {
17518                 ArrayList<String> noAction = new ArrayList<String>(1);
17519                 noAction.add(null);
17520                 actions = noAction.iterator();
17521             }
17522 
17523             // Collect stickies of users
17524             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17525             while (actions.hasNext()) {
17526                 String action = actions.next();
17527                 for (int id : userIds) {
17528                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17529                     if (stickies != null) {
17530                         ArrayList<Intent> intents = stickies.get(action);
17531                         if (intents != null) {
17532                             if (stickyIntents == null) {
17533                                 stickyIntents = new ArrayList<Intent>();
17534                             }
17535                             stickyIntents.addAll(intents);
17536                         }
17537                     }
17538                 }
17539             }
17540         }
17541 
17542         ArrayList<Intent> allSticky = null;
17543         if (stickyIntents != null) {
17544             final ContentResolver resolver = mContext.getContentResolver();
17545             // Look for any matching sticky broadcasts...
17546             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17547                 Intent intent = stickyIntents.get(i);
17548                 // If intent has scheme "content", it will need to acccess
17549                 // provider that needs to lock mProviderMap in ActivityThread
17550                 // and also it may need to wait application response, so we
17551                 // cannot lock ActivityManagerService here.
17552                 if (filter.match(resolver, intent, true, TAG) >= 0) {
17553                     if (allSticky == null) {
17554                         allSticky = new ArrayList<Intent>();
17555                     }
17556                     allSticky.add(intent);
17557                 }
17558             }
17559         }
17560 
17561         // The first sticky in the list is returned directly back to the client.
17562         Intent sticky = allSticky != null ? allSticky.get(0) : null;
17563         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17564         if (receiver == null) {
17565             return sticky;
17566         }
17567 
17568         synchronized (this) {
17569             if (callerApp != null && (callerApp.thread == null
17570                     || callerApp.thread.asBinder() != caller.asBinder())) {
17571                 // Original caller already died
17572                 return null;
17573             }
17574             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17575             if (rl == null) {
17576                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17577                         userId, receiver);
17578                 if (rl.app != null) {
17579                     rl.app.receivers.add(rl);
17580                 } else {
17581                     try {
17582                         receiver.asBinder().linkToDeath(rl, 0);
17583                     } catch (RemoteException e) {
17584                         return sticky;
17585                     }
17586                     rl.linkedToDeath = true;
17587                 }
17588                 mRegisteredReceivers.put(receiver.asBinder(), rl);
17589             } else if (rl.uid != callingUid) {
17590                 throw new IllegalArgumentException(
17591                         "Receiver requested to register for uid " + callingUid
17592                         + " was previously registered for uid " + rl.uid);
17593             } else if (rl.pid != callingPid) {
17594                 throw new IllegalArgumentException(
17595                         "Receiver requested to register for pid " + callingPid
17596                         + " was previously registered for pid " + rl.pid);
17597             } else if (rl.userId != userId) {
17598                 throw new IllegalArgumentException(
17599                         "Receiver requested to register for user " + userId
17600                         + " was previously registered for user " + rl.userId);
17601             }
17602             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17603                     permission, callingUid, userId);
17604             rl.add(bf);
17605             if (!bf.debugCheck()) {
17606                 Slog.w(TAG, "==> For Dynamic broadcast");
17607             }
17608             mReceiverResolver.addFilter(bf);
17609 
17610             // Enqueue broadcasts for all existing stickies that match
17611             // this filter.
17612             if (allSticky != null) {
17613                 ArrayList receivers = new ArrayList();
17614                 receivers.add(bf);
17615 
17616                 final int stickyCount = allSticky.size();
17617                 for (int i = 0; i < stickyCount; i++) {
17618                     Intent intent = allSticky.get(i);
17619                     BroadcastQueue queue = broadcastQueueForIntent(intent);
17620                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17621                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17622                             null, 0, null, null, false, true, true, -1);
17623                     queue.enqueueParallelBroadcastLocked(r);
17624                     queue.scheduleBroadcastsLocked();
17625                 }
17626             }
17627 
17628             return sticky;
17629         }
17630     }
17631 
unregisterReceiver(IIntentReceiver receiver)17632     public void unregisterReceiver(IIntentReceiver receiver) {
17633         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17634 
17635         final long origId = Binder.clearCallingIdentity();
17636         try {
17637             boolean doTrim = false;
17638 
17639             synchronized(this) {
17640                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17641                 if (rl != null) {
17642                     final BroadcastRecord r = rl.curBroadcast;
17643                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17644                         final boolean doNext = r.queue.finishReceiverLocked(
17645                                 r, r.resultCode, r.resultData, r.resultExtras,
17646                                 r.resultAbort, false);
17647                         if (doNext) {
17648                             doTrim = true;
17649                             r.queue.processNextBroadcast(false);
17650                         }
17651                     }
17652 
17653                     if (rl.app != null) {
17654                         rl.app.receivers.remove(rl);
17655                     }
17656                     removeReceiverLocked(rl);
17657                     if (rl.linkedToDeath) {
17658                         rl.linkedToDeath = false;
17659                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17660                     }
17661                 }
17662             }
17663 
17664             // If we actually concluded any broadcasts, we might now be able
17665             // to trim the recipients' apps from our working set
17666             if (doTrim) {
17667                 trimApplications();
17668                 return;
17669             }
17670 
17671         } finally {
17672             Binder.restoreCallingIdentity(origId);
17673         }
17674     }
17675 
removeReceiverLocked(ReceiverList rl)17676     void removeReceiverLocked(ReceiverList rl) {
17677         mRegisteredReceivers.remove(rl.receiver.asBinder());
17678         for (int i = rl.size() - 1; i >= 0; i--) {
17679             mReceiverResolver.removeFilter(rl.get(i));
17680         }
17681     }
17682 
sendPackageBroadcastLocked(int cmd, String[] packages, int userId)17683     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17684         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17685             ProcessRecord r = mLruProcesses.get(i);
17686             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17687                 try {
17688                     r.thread.dispatchPackageBroadcast(cmd, packages);
17689                 } catch (RemoteException ex) {
17690                 }
17691             }
17692         }
17693     }
17694 
collectReceiverComponents(Intent intent, String resolvedType, int callingUid, int[] users)17695     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17696             int callingUid, int[] users) {
17697         // TODO: come back and remove this assumption to triage all broadcasts
17698         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17699 
17700         List<ResolveInfo> receivers = null;
17701         try {
17702             HashSet<ComponentName> singleUserReceivers = null;
17703             boolean scannedFirstReceivers = false;
17704             for (int user : users) {
17705                 // Skip users that have Shell restrictions, with exception of always permitted
17706                 // Shell broadcasts
17707                 if (callingUid == Process.SHELL_UID
17708                         && mUserController.hasUserRestriction(
17709                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17710                         && !isPermittedShellBroadcast(intent)) {
17711                     continue;
17712                 }
17713                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17714                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17715                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17716                     // If this is not the system user, we need to check for
17717                     // any receivers that should be filtered out.
17718                     for (int i=0; i<newReceivers.size(); i++) {
17719                         ResolveInfo ri = newReceivers.get(i);
17720                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17721                             newReceivers.remove(i);
17722                             i--;
17723                         }
17724                     }
17725                 }
17726                 if (newReceivers != null && newReceivers.size() == 0) {
17727                     newReceivers = null;
17728                 }
17729                 if (receivers == null) {
17730                     receivers = newReceivers;
17731                 } else if (newReceivers != null) {
17732                     // We need to concatenate the additional receivers
17733                     // found with what we have do far.  This would be easy,
17734                     // but we also need to de-dup any receivers that are
17735                     // singleUser.
17736                     if (!scannedFirstReceivers) {
17737                         // Collect any single user receivers we had already retrieved.
17738                         scannedFirstReceivers = true;
17739                         for (int i=0; i<receivers.size(); i++) {
17740                             ResolveInfo ri = receivers.get(i);
17741                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17742                                 ComponentName cn = new ComponentName(
17743                                         ri.activityInfo.packageName, ri.activityInfo.name);
17744                                 if (singleUserReceivers == null) {
17745                                     singleUserReceivers = new HashSet<ComponentName>();
17746                                 }
17747                                 singleUserReceivers.add(cn);
17748                             }
17749                         }
17750                     }
17751                     // Add the new results to the existing results, tracking
17752                     // and de-dupping single user receivers.
17753                     for (int i=0; i<newReceivers.size(); i++) {
17754                         ResolveInfo ri = newReceivers.get(i);
17755                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17756                             ComponentName cn = new ComponentName(
17757                                     ri.activityInfo.packageName, ri.activityInfo.name);
17758                             if (singleUserReceivers == null) {
17759                                 singleUserReceivers = new HashSet<ComponentName>();
17760                             }
17761                             if (!singleUserReceivers.contains(cn)) {
17762                                 singleUserReceivers.add(cn);
17763                                 receivers.add(ri);
17764                             }
17765                         } else {
17766                             receivers.add(ri);
17767                         }
17768                     }
17769                 }
17770             }
17771         } catch (RemoteException ex) {
17772             // pm is in same process, this will never happen.
17773         }
17774         return receivers;
17775     }
17776 
isPermittedShellBroadcast(Intent intent)17777     private boolean isPermittedShellBroadcast(Intent intent) {
17778         // remote bugreport should always be allowed to be taken
17779         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17780     }
17781 
checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp, String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers)17782     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17783             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17784         final String action = intent.getAction();
17785         if (isProtectedBroadcast
17786                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17787                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17788                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17789                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17790                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17791                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17792                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17793                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17794                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17795                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17796             // Broadcast is either protected, or it's a public action that
17797             // we've relaxed, so it's fine for system internals to send.
17798             return;
17799         }
17800 
17801         // This broadcast may be a problem...  but there are often system components that
17802         // want to send an internal broadcast to themselves, which is annoying to have to
17803         // explicitly list each action as a protected broadcast, so we will check for that
17804         // one safe case and allow it: an explicit broadcast, only being received by something
17805         // that has protected itself.
17806         if (receivers != null && receivers.size() > 0
17807                 && (intent.getPackage() != null || intent.getComponent() != null)) {
17808             boolean allProtected = true;
17809             for (int i = receivers.size()-1; i >= 0; i--) {
17810                 Object target = receivers.get(i);
17811                 if (target instanceof ResolveInfo) {
17812                     ResolveInfo ri = (ResolveInfo)target;
17813                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17814                         allProtected = false;
17815                         break;
17816                     }
17817                 } else {
17818                     BroadcastFilter bf = (BroadcastFilter)target;
17819                     if (bf.requiredPermission == null) {
17820                         allProtected = false;
17821                         break;
17822                     }
17823                 }
17824             }
17825             if (allProtected) {
17826                 // All safe!
17827                 return;
17828             }
17829         }
17830 
17831         // The vast majority of broadcasts sent from system internals
17832         // should be protected to avoid security holes, so yell loudly
17833         // to ensure we examine these cases.
17834         if (callerApp != null) {
17835             Log.wtf(TAG, "Sending non-protected broadcast " + action
17836                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17837                     new Throwable());
17838         } else {
17839             Log.wtf(TAG, "Sending non-protected broadcast " + action
17840                             + " from system uid " + UserHandle.formatUid(callingUid)
17841                             + " pkg " + callerPackage,
17842                     new Throwable());
17843         }
17844     }
17845 
broadcastIntentLocked(ProcessRecord callerApp, String callerPackage, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean ordered, boolean sticky, int callingPid, int callingUid, int userId)17846     final int broadcastIntentLocked(ProcessRecord callerApp,
17847             String callerPackage, Intent intent, String resolvedType,
17848             IIntentReceiver resultTo, int resultCode, String resultData,
17849             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17850             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17851         intent = new Intent(intent);
17852 
17853         // By default broadcasts do not go to stopped apps.
17854         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17855 
17856         // If we have not finished booting, don't allow this to launch new processes.
17857         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17858             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17859         }
17860 
17861         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17862                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17863                 + " ordered=" + ordered + " userid=" + userId);
17864         if ((resultTo != null) && !ordered) {
17865             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17866         }
17867 
17868         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17869                 ALLOW_NON_FULL, "broadcast", callerPackage);
17870 
17871         // Make sure that the user who is receiving this broadcast is running.
17872         // If not, we will just skip it. Make an exception for shutdown broadcasts
17873         // and upgrade steps.
17874 
17875         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17876             if ((callingUid != Process.SYSTEM_UID
17877                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17878                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17879                 Slog.w(TAG, "Skipping broadcast of " + intent
17880                         + ": user " + userId + " is stopped");
17881                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17882             }
17883         }
17884 
17885         BroadcastOptions brOptions = null;
17886         if (bOptions != null) {
17887             brOptions = new BroadcastOptions(bOptions);
17888             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17889                 // See if the caller is allowed to do this.  Note we are checking against
17890                 // the actual real caller (not whoever provided the operation as say a
17891                 // PendingIntent), because that who is actually supplied the arguments.
17892                 if (checkComponentPermission(
17893                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17894                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17895                         != PackageManager.PERMISSION_GRANTED) {
17896                     String msg = "Permission Denial: " + intent.getAction()
17897                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17898                             + ", uid=" + callingUid + ")"
17899                             + " requires "
17900                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17901                     Slog.w(TAG, msg);
17902                     throw new SecurityException(msg);
17903                 }
17904             }
17905         }
17906 
17907         // Verify that protected broadcasts are only being sent by system code,
17908         // and that system code is only sending protected broadcasts.
17909         final String action = intent.getAction();
17910         final boolean isProtectedBroadcast;
17911         try {
17912             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17913         } catch (RemoteException e) {
17914             Slog.w(TAG, "Remote exception", e);
17915             return ActivityManager.BROADCAST_SUCCESS;
17916         }
17917 
17918         final boolean isCallerSystem;
17919         switch (UserHandle.getAppId(callingUid)) {
17920             case Process.ROOT_UID:
17921             case Process.SYSTEM_UID:
17922             case Process.PHONE_UID:
17923             case Process.BLUETOOTH_UID:
17924             case Process.NFC_UID:
17925                 isCallerSystem = true;
17926                 break;
17927             default:
17928                 isCallerSystem = (callerApp != null) && callerApp.persistent;
17929                 break;
17930         }
17931 
17932         // First line security check before anything else: stop non-system apps from
17933         // sending protected broadcasts.
17934         if (!isCallerSystem) {
17935             if (isProtectedBroadcast) {
17936                 String msg = "Permission Denial: not allowed to send broadcast "
17937                         + action + " from pid="
17938                         + callingPid + ", uid=" + callingUid;
17939                 Slog.w(TAG, msg);
17940                 throw new SecurityException(msg);
17941 
17942             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17943                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
17944                 // Special case for compatibility: we don't want apps to send this,
17945                 // but historically it has not been protected and apps may be using it
17946                 // to poke their own app widget.  So, instead of making it protected,
17947                 // just limit it to the caller.
17948                 if (callerPackage == null) {
17949                     String msg = "Permission Denial: not allowed to send broadcast "
17950                             + action + " from unknown caller.";
17951                     Slog.w(TAG, msg);
17952                     throw new SecurityException(msg);
17953                 } else if (intent.getComponent() != null) {
17954                     // They are good enough to send to an explicit component...  verify
17955                     // it is being sent to the calling app.
17956                     if (!intent.getComponent().getPackageName().equals(
17957                             callerPackage)) {
17958                         String msg = "Permission Denial: not allowed to send broadcast "
17959                                 + action + " to "
17960                                 + intent.getComponent().getPackageName() + " from "
17961                                 + callerPackage;
17962                         Slog.w(TAG, msg);
17963                         throw new SecurityException(msg);
17964                     }
17965                 } else {
17966                     // Limit broadcast to their own package.
17967                     intent.setPackage(callerPackage);
17968                 }
17969             }
17970         }
17971 
17972         if (action != null) {
17973             switch (action) {
17974                 case Intent.ACTION_UID_REMOVED:
17975                 case Intent.ACTION_PACKAGE_REMOVED:
17976                 case Intent.ACTION_PACKAGE_CHANGED:
17977                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
17978                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
17979                 case Intent.ACTION_PACKAGES_SUSPENDED:
17980                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
17981                     // Handle special intents: if this broadcast is from the package
17982                     // manager about a package being removed, we need to remove all of
17983                     // its activities from the history stack.
17984                     if (checkComponentPermission(
17985                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
17986                             callingPid, callingUid, -1, true)
17987                             != PackageManager.PERMISSION_GRANTED) {
17988                         String msg = "Permission Denial: " + intent.getAction()
17989                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
17990                                 + ", uid=" + callingUid + ")"
17991                                 + " requires "
17992                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
17993                         Slog.w(TAG, msg);
17994                         throw new SecurityException(msg);
17995                     }
17996                     switch (action) {
17997                         case Intent.ACTION_UID_REMOVED:
17998                             final Bundle intentExtras = intent.getExtras();
17999                             final int uid = intentExtras != null
18000                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18001                             if (uid >= 0) {
18002                                 mBatteryStatsService.removeUid(uid);
18003                                 mAppOpsService.uidRemoved(uid);
18004                             }
18005                             break;
18006                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18007                             // If resources are unavailable just force stop all those packages
18008                             // and flush the attribute cache as well.
18009                             String list[] =
18010                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18011                             if (list != null && list.length > 0) {
18012                                 for (int i = 0; i < list.length; i++) {
18013                                     forceStopPackageLocked(list[i], -1, false, true, true,
18014                                             false, false, userId, "storage unmount");
18015                                 }
18016                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18017                                 sendPackageBroadcastLocked(
18018                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18019                                         userId);
18020                             }
18021                             break;
18022                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18023                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18024                             break;
18025                         case Intent.ACTION_PACKAGE_REMOVED:
18026                         case Intent.ACTION_PACKAGE_CHANGED:
18027                             Uri data = intent.getData();
18028                             String ssp;
18029                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18030                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18031                                 final boolean replacing =
18032                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18033                                 final boolean killProcess =
18034                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18035                                 final boolean fullUninstall = removed && !replacing;
18036                                 if (removed) {
18037                                     if (killProcess) {
18038                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
18039                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18040                                                 false, true, true, false, fullUninstall, userId,
18041                                                 removed ? "pkg removed" : "pkg changed");
18042                                     }
18043                                     final int cmd = killProcess
18044                                             ? IApplicationThread.PACKAGE_REMOVED
18045                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18046                                     sendPackageBroadcastLocked(cmd,
18047                                             new String[] {ssp}, userId);
18048                                     if (fullUninstall) {
18049                                         mAppOpsService.packageRemoved(
18050                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18051 
18052                                         // Remove all permissions granted from/to this package
18053                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
18054 
18055                                         removeTasksByPackageNameLocked(ssp, userId);
18056 
18057                                         // Hide the "unsupported display" dialog if necessary.
18058                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18059                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18060                                             mUnsupportedDisplaySizeDialog.dismiss();
18061                                             mUnsupportedDisplaySizeDialog = null;
18062                                         }
18063                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
18064                                         mBatteryStatsService.notePackageUninstalled(ssp);
18065                                     }
18066                                 } else {
18067                                     if (killProcess) {
18068                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
18069                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18070                                                 userId, ProcessList.INVALID_ADJ,
18071                                                 false, true, true, false, "change " + ssp);
18072                                     }
18073                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18074                                             intent.getStringArrayExtra(
18075                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18076                                 }
18077                             }
18078                             break;
18079                         case Intent.ACTION_PACKAGES_SUSPENDED:
18080                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
18081                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18082                                     intent.getAction());
18083                             final String[] packageNames = intent.getStringArrayExtra(
18084                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
18085                             final int userHandle = intent.getIntExtra(
18086                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18087 
18088                             synchronized(ActivityManagerService.this) {
18089                                 mRecentTasks.onPackagesSuspendedChanged(
18090                                         packageNames, suspended, userHandle);
18091                             }
18092                             break;
18093                     }
18094                     break;
18095                 case Intent.ACTION_PACKAGE_REPLACED:
18096                 {
18097                     final Uri data = intent.getData();
18098                     final String ssp;
18099                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18100                         final ApplicationInfo aInfo =
18101                                 getPackageManagerInternalLocked().getApplicationInfo(
18102                                         ssp,
18103                                         userId);
18104                         if (aInfo == null) {
18105                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18106                                     + " ssp=" + ssp + " data=" + data);
18107                             return ActivityManager.BROADCAST_SUCCESS;
18108                         }
18109                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18110                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18111                                 new String[] {ssp}, userId);
18112                     }
18113                     break;
18114                 }
18115                 case Intent.ACTION_PACKAGE_ADDED:
18116                 {
18117                     // Special case for adding a package: by default turn on compatibility mode.
18118                     Uri data = intent.getData();
18119                     String ssp;
18120                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18121                         final boolean replacing =
18122                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18123                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18124 
18125                         try {
18126                             ApplicationInfo ai = AppGlobals.getPackageManager().
18127                                     getApplicationInfo(ssp, 0, 0);
18128                             mBatteryStatsService.notePackageInstalled(ssp,
18129                                     ai != null ? ai.versionCode : 0);
18130                         } catch (RemoteException e) {
18131                         }
18132                     }
18133                     break;
18134                 }
18135                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18136                 {
18137                     Uri data = intent.getData();
18138                     String ssp;
18139                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18140                         // Hide the "unsupported display" dialog if necessary.
18141                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18142                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18143                             mUnsupportedDisplaySizeDialog.dismiss();
18144                             mUnsupportedDisplaySizeDialog = null;
18145                         }
18146                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
18147                     }
18148                     break;
18149                 }
18150                 case Intent.ACTION_TIMEZONE_CHANGED:
18151                     // If this is the time zone changed action, queue up a message that will reset
18152                     // the timezone of all currently running processes. This message will get
18153                     // queued up before the broadcast happens.
18154                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18155                     break;
18156                 case Intent.ACTION_TIME_CHANGED:
18157                     // If the user set the time, let all running processes know.
18158                     final int is24Hour =
18159                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18160                                     : 0;
18161                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18162                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18163                     synchronized (stats) {
18164                         stats.noteCurrentTimeChangedLocked();
18165                     }
18166                     break;
18167                 case Intent.ACTION_CLEAR_DNS_CACHE:
18168                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18169                     break;
18170                 case Proxy.PROXY_CHANGE_ACTION:
18171                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18172                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18173                     break;
18174                 case android.hardware.Camera.ACTION_NEW_PICTURE:
18175                 case android.hardware.Camera.ACTION_NEW_VIDEO:
18176                     // These broadcasts are no longer allowed by the system, since they can
18177                     // cause significant thrashing at a crictical point (using the camera).
18178                     // Apps should use JobScehduler to monitor for media provider changes.
18179                     Slog.w(TAG, action + " no longer allowed; dropping from "
18180                             + UserHandle.formatUid(callingUid));
18181                     if (resultTo != null) {
18182                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
18183                         try {
18184                             queue.performReceiveLocked(callerApp, resultTo, intent,
18185                                     Activity.RESULT_CANCELED, null, null,
18186                                     false, false, userId);
18187                         } catch (RemoteException e) {
18188                             Slog.w(TAG, "Failure ["
18189                                     + queue.mQueueName + "] sending broadcast result of "
18190                                     + intent, e);
18191 
18192                         }
18193                     }
18194                     // Lie; we don't want to crash the app.
18195                     return ActivityManager.BROADCAST_SUCCESS;
18196             }
18197         }
18198 
18199         // Add to the sticky list if requested.
18200         if (sticky) {
18201             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18202                     callingPid, callingUid)
18203                     != PackageManager.PERMISSION_GRANTED) {
18204                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18205                         + callingPid + ", uid=" + callingUid
18206                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18207                 Slog.w(TAG, msg);
18208                 throw new SecurityException(msg);
18209             }
18210             if (requiredPermissions != null && requiredPermissions.length > 0) {
18211                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18212                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
18213                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18214             }
18215             if (intent.getComponent() != null) {
18216                 throw new SecurityException(
18217                         "Sticky broadcasts can't target a specific component");
18218             }
18219             // We use userId directly here, since the "all" target is maintained
18220             // as a separate set of sticky broadcasts.
18221             if (userId != UserHandle.USER_ALL) {
18222                 // But first, if this is not a broadcast to all users, then
18223                 // make sure it doesn't conflict with an existing broadcast to
18224                 // all users.
18225                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18226                         UserHandle.USER_ALL);
18227                 if (stickies != null) {
18228                     ArrayList<Intent> list = stickies.get(intent.getAction());
18229                     if (list != null) {
18230                         int N = list.size();
18231                         int i;
18232                         for (i=0; i<N; i++) {
18233                             if (intent.filterEquals(list.get(i))) {
18234                                 throw new IllegalArgumentException(
18235                                         "Sticky broadcast " + intent + " for user "
18236                                         + userId + " conflicts with existing global broadcast");
18237                             }
18238                         }
18239                     }
18240                 }
18241             }
18242             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18243             if (stickies == null) {
18244                 stickies = new ArrayMap<>();
18245                 mStickyBroadcasts.put(userId, stickies);
18246             }
18247             ArrayList<Intent> list = stickies.get(intent.getAction());
18248             if (list == null) {
18249                 list = new ArrayList<>();
18250                 stickies.put(intent.getAction(), list);
18251             }
18252             final int stickiesCount = list.size();
18253             int i;
18254             for (i = 0; i < stickiesCount; i++) {
18255                 if (intent.filterEquals(list.get(i))) {
18256                     // This sticky already exists, replace it.
18257                     list.set(i, new Intent(intent));
18258                     break;
18259                 }
18260             }
18261             if (i >= stickiesCount) {
18262                 list.add(new Intent(intent));
18263             }
18264         }
18265 
18266         int[] users;
18267         if (userId == UserHandle.USER_ALL) {
18268             // Caller wants broadcast to go to all started users.
18269             users = mUserController.getStartedUserArrayLocked();
18270         } else {
18271             // Caller wants broadcast to go to one specific user.
18272             users = new int[] {userId};
18273         }
18274 
18275         // Figure out who all will receive this broadcast.
18276         List receivers = null;
18277         List<BroadcastFilter> registeredReceivers = null;
18278         // Need to resolve the intent to interested receivers...
18279         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18280                  == 0) {
18281             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18282         }
18283         if (intent.getComponent() == null) {
18284             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18285                 // Query one target user at a time, excluding shell-restricted users
18286                 for (int i = 0; i < users.length; i++) {
18287                     if (mUserController.hasUserRestriction(
18288                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18289                         continue;
18290                     }
18291                     List<BroadcastFilter> registeredReceiversForUser =
18292                             mReceiverResolver.queryIntent(intent,
18293                                     resolvedType, false, users[i]);
18294                     if (registeredReceivers == null) {
18295                         registeredReceivers = registeredReceiversForUser;
18296                     } else if (registeredReceiversForUser != null) {
18297                         registeredReceivers.addAll(registeredReceiversForUser);
18298                     }
18299                 }
18300             } else {
18301                 registeredReceivers = mReceiverResolver.queryIntent(intent,
18302                         resolvedType, false, userId);
18303             }
18304         }
18305 
18306         final boolean replacePending =
18307                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18308 
18309         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18310                 + " replacePending=" + replacePending);
18311 
18312         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18313         if (!ordered && NR > 0) {
18314             // If we are not serializing this broadcast, then send the
18315             // registered receivers separately so they don't wait for the
18316             // components to be launched.
18317             if (isCallerSystem) {
18318                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18319                         isProtectedBroadcast, registeredReceivers);
18320             }
18321             final BroadcastQueue queue = broadcastQueueForIntent(intent);
18322             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18323                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18324                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18325                     resultExtras, ordered, sticky, false, userId);
18326             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18327             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18328             if (!replaced) {
18329                 queue.enqueueParallelBroadcastLocked(r);
18330                 queue.scheduleBroadcastsLocked();
18331             }
18332             registeredReceivers = null;
18333             NR = 0;
18334         }
18335 
18336         // Merge into one list.
18337         int ir = 0;
18338         if (receivers != null) {
18339             // A special case for PACKAGE_ADDED: do not allow the package
18340             // being added to see this broadcast.  This prevents them from
18341             // using this as a back door to get run as soon as they are
18342             // installed.  Maybe in the future we want to have a special install
18343             // broadcast or such for apps, but we'd like to deliberately make
18344             // this decision.
18345             String skipPackages[] = null;
18346             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18347                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18348                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18349                 Uri data = intent.getData();
18350                 if (data != null) {
18351                     String pkgName = data.getSchemeSpecificPart();
18352                     if (pkgName != null) {
18353                         skipPackages = new String[] { pkgName };
18354                     }
18355                 }
18356             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18357                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18358             }
18359             if (skipPackages != null && (skipPackages.length > 0)) {
18360                 for (String skipPackage : skipPackages) {
18361                     if (skipPackage != null) {
18362                         int NT = receivers.size();
18363                         for (int it=0; it<NT; it++) {
18364                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
18365                             if (curt.activityInfo.packageName.equals(skipPackage)) {
18366                                 receivers.remove(it);
18367                                 it--;
18368                                 NT--;
18369                             }
18370                         }
18371                     }
18372                 }
18373             }
18374 
18375             int NT = receivers != null ? receivers.size() : 0;
18376             int it = 0;
18377             ResolveInfo curt = null;
18378             BroadcastFilter curr = null;
18379             while (it < NT && ir < NR) {
18380                 if (curt == null) {
18381                     curt = (ResolveInfo)receivers.get(it);
18382                 }
18383                 if (curr == null) {
18384                     curr = registeredReceivers.get(ir);
18385                 }
18386                 if (curr.getPriority() >= curt.priority) {
18387                     // Insert this broadcast record into the final list.
18388                     receivers.add(it, curr);
18389                     ir++;
18390                     curr = null;
18391                     it++;
18392                     NT++;
18393                 } else {
18394                     // Skip to the next ResolveInfo in the final list.
18395                     it++;
18396                     curt = null;
18397                 }
18398             }
18399         }
18400         while (ir < NR) {
18401             if (receivers == null) {
18402                 receivers = new ArrayList();
18403             }
18404             receivers.add(registeredReceivers.get(ir));
18405             ir++;
18406         }
18407 
18408         if (isCallerSystem) {
18409             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18410                     isProtectedBroadcast, receivers);
18411         }
18412 
18413         if ((receivers != null && receivers.size() > 0)
18414                 || resultTo != null) {
18415             BroadcastQueue queue = broadcastQueueForIntent(intent);
18416             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18417                     callerPackage, callingPid, callingUid, resolvedType,
18418                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18419                     resultData, resultExtras, ordered, sticky, false, userId);
18420 
18421             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18422                     + ": prev had " + queue.mOrderedBroadcasts.size());
18423             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18424                     "Enqueueing broadcast " + r.intent.getAction());
18425 
18426             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18427             if (!replaced) {
18428                 queue.enqueueOrderedBroadcastLocked(r);
18429                 queue.scheduleBroadcastsLocked();
18430             }
18431         } else {
18432             // There was nobody interested in the broadcast, but we still want to record
18433             // that it happened.
18434             if (intent.getComponent() == null && intent.getPackage() == null
18435                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18436                 // This was an implicit broadcast... let's record it for posterity.
18437                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18438             }
18439         }
18440 
18441         return ActivityManager.BROADCAST_SUCCESS;
18442     }
18443 
addBroadcastStatLocked(String action, String srcPackage, int receiveCount, int skipCount, long dispatchTime)18444     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18445             int skipCount, long dispatchTime) {
18446         final long now = SystemClock.elapsedRealtime();
18447         if (mCurBroadcastStats == null ||
18448                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18449             mLastBroadcastStats = mCurBroadcastStats;
18450             if (mLastBroadcastStats != null) {
18451                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18452                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18453             }
18454             mCurBroadcastStats = new BroadcastStats();
18455         }
18456         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18457     }
18458 
verifyBroadcastLocked(Intent intent)18459     final Intent verifyBroadcastLocked(Intent intent) {
18460         // Refuse possible leaked file descriptors
18461         if (intent != null && intent.hasFileDescriptors() == true) {
18462             throw new IllegalArgumentException("File descriptors passed in Intent");
18463         }
18464 
18465         int flags = intent.getFlags();
18466 
18467         if (!mProcessesReady) {
18468             // if the caller really truly claims to know what they're doing, go
18469             // ahead and allow the broadcast without launching any receivers
18470             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18471                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18472             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18473                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18474                         + " before boot completion");
18475                 throw new IllegalStateException("Cannot broadcast before boot completed");
18476             }
18477         }
18478 
18479         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18480             throw new IllegalArgumentException(
18481                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18482         }
18483 
18484         return intent;
18485     }
18486 
broadcastIntent(IApplicationThread caller, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions, boolean serialized, boolean sticky, int userId)18487     public final int broadcastIntent(IApplicationThread caller,
18488             Intent intent, String resolvedType, IIntentReceiver resultTo,
18489             int resultCode, String resultData, Bundle resultExtras,
18490             String[] requiredPermissions, int appOp, Bundle bOptions,
18491             boolean serialized, boolean sticky, int userId) {
18492         enforceNotIsolatedCaller("broadcastIntent");
18493         synchronized(this) {
18494             intent = verifyBroadcastLocked(intent);
18495 
18496             final ProcessRecord callerApp = getRecordForAppLocked(caller);
18497             final int callingPid = Binder.getCallingPid();
18498             final int callingUid = Binder.getCallingUid();
18499             final long origId = Binder.clearCallingIdentity();
18500             int res = broadcastIntentLocked(callerApp,
18501                     callerApp != null ? callerApp.info.packageName : null,
18502                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18503                     requiredPermissions, appOp, bOptions, serialized, sticky,
18504                     callingPid, callingUid, userId);
18505             Binder.restoreCallingIdentity(origId);
18506             return res;
18507         }
18508     }
18509 
18510 
broadcastIntentInPackage(String packageName, int uid, Intent intent, String resolvedType, IIntentReceiver resultTo, int resultCode, String resultData, Bundle resultExtras, String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky, int userId)18511     int broadcastIntentInPackage(String packageName, int uid,
18512             Intent intent, String resolvedType, IIntentReceiver resultTo,
18513             int resultCode, String resultData, Bundle resultExtras,
18514             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18515             int userId) {
18516         synchronized(this) {
18517             intent = verifyBroadcastLocked(intent);
18518 
18519             final long origId = Binder.clearCallingIdentity();
18520             String[] requiredPermissions = requiredPermission == null ? null
18521                     : new String[] {requiredPermission};
18522             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18523                     resultTo, resultCode, resultData, resultExtras,
18524                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18525                     sticky, -1, uid, userId);
18526             Binder.restoreCallingIdentity(origId);
18527             return res;
18528         }
18529     }
18530 
unbroadcastIntent(IApplicationThread caller, Intent intent, int userId)18531     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18532         // Refuse possible leaked file descriptors
18533         if (intent != null && intent.hasFileDescriptors() == true) {
18534             throw new IllegalArgumentException("File descriptors passed in Intent");
18535         }
18536 
18537         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18538                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18539 
18540         synchronized(this) {
18541             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18542                     != PackageManager.PERMISSION_GRANTED) {
18543                 String msg = "Permission Denial: unbroadcastIntent() from pid="
18544                         + Binder.getCallingPid()
18545                         + ", uid=" + Binder.getCallingUid()
18546                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18547                 Slog.w(TAG, msg);
18548                 throw new SecurityException(msg);
18549             }
18550             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18551             if (stickies != null) {
18552                 ArrayList<Intent> list = stickies.get(intent.getAction());
18553                 if (list != null) {
18554                     int N = list.size();
18555                     int i;
18556                     for (i=0; i<N; i++) {
18557                         if (intent.filterEquals(list.get(i))) {
18558                             list.remove(i);
18559                             break;
18560                         }
18561                     }
18562                     if (list.size() <= 0) {
18563                         stickies.remove(intent.getAction());
18564                     }
18565                 }
18566                 if (stickies.size() <= 0) {
18567                     mStickyBroadcasts.remove(userId);
18568                 }
18569             }
18570         }
18571     }
18572 
backgroundServicesFinishedLocked(int userId)18573     void backgroundServicesFinishedLocked(int userId) {
18574         for (BroadcastQueue queue : mBroadcastQueues) {
18575             queue.backgroundServicesFinishedLocked(userId);
18576         }
18577     }
18578 
finishReceiver(IBinder who, int resultCode, String resultData, Bundle resultExtras, boolean resultAbort, int flags)18579     public void finishReceiver(IBinder who, int resultCode, String resultData,
18580             Bundle resultExtras, boolean resultAbort, int flags) {
18581         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18582 
18583         // Refuse possible leaked file descriptors
18584         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18585             throw new IllegalArgumentException("File descriptors passed in Bundle");
18586         }
18587 
18588         final long origId = Binder.clearCallingIdentity();
18589         try {
18590             boolean doNext = false;
18591             BroadcastRecord r;
18592 
18593             synchronized(this) {
18594                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18595                         ? mFgBroadcastQueue : mBgBroadcastQueue;
18596                 r = queue.getMatchingOrderedReceiver(who);
18597                 if (r != null) {
18598                     doNext = r.queue.finishReceiverLocked(r, resultCode,
18599                         resultData, resultExtras, resultAbort, true);
18600                 }
18601             }
18602 
18603             if (doNext) {
18604                 r.queue.processNextBroadcast(false);
18605             }
18606             trimApplications();
18607         } finally {
18608             Binder.restoreCallingIdentity(origId);
18609         }
18610     }
18611 
18612     // =========================================================
18613     // INSTRUMENTATION
18614     // =========================================================
18615 
startInstrumentation(ComponentName className, String profileFile, int flags, Bundle arguments, IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection, int userId, String abiOverride)18616     public boolean startInstrumentation(ComponentName className,
18617             String profileFile, int flags, Bundle arguments,
18618             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18619             int userId, String abiOverride) {
18620         enforceNotIsolatedCaller("startInstrumentation");
18621         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18622                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18623         // Refuse possible leaked file descriptors
18624         if (arguments != null && arguments.hasFileDescriptors()) {
18625             throw new IllegalArgumentException("File descriptors passed in Bundle");
18626         }
18627 
18628         synchronized(this) {
18629             InstrumentationInfo ii = null;
18630             ApplicationInfo ai = null;
18631             try {
18632                 ii = mContext.getPackageManager().getInstrumentationInfo(
18633                     className, STOCK_PM_FLAGS);
18634                 ai = AppGlobals.getPackageManager().getApplicationInfo(
18635                         ii.targetPackage, STOCK_PM_FLAGS, userId);
18636             } catch (PackageManager.NameNotFoundException e) {
18637             } catch (RemoteException e) {
18638             }
18639             if (ii == null) {
18640                 reportStartInstrumentationFailureLocked(watcher, className,
18641                         "Unable to find instrumentation info for: " + className);
18642                 return false;
18643             }
18644             if (ai == null) {
18645                 reportStartInstrumentationFailureLocked(watcher, className,
18646                         "Unable to find instrumentation target package: " + ii.targetPackage);
18647                 return false;
18648             }
18649             if (!ai.hasCode()) {
18650                 reportStartInstrumentationFailureLocked(watcher, className,
18651                         "Instrumentation target has no code: " + ii.targetPackage);
18652                 return false;
18653             }
18654 
18655             int match = mContext.getPackageManager().checkSignatures(
18656                     ii.targetPackage, ii.packageName);
18657             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18658                 String msg = "Permission Denial: starting instrumentation "
18659                         + className + " from pid="
18660                         + Binder.getCallingPid()
18661                         + ", uid=" + Binder.getCallingPid()
18662                         + " not allowed because package " + ii.packageName
18663                         + " does not have a signature matching the target "
18664                         + ii.targetPackage;
18665                 reportStartInstrumentationFailureLocked(watcher, className, msg);
18666                 throw new SecurityException(msg);
18667             }
18668 
18669             final long origId = Binder.clearCallingIdentity();
18670             // Instrumentation can kill and relaunch even persistent processes
18671             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18672                     "start instr");
18673             ProcessRecord app = addAppLocked(ai, false, abiOverride);
18674             app.instrumentationClass = className;
18675             app.instrumentationInfo = ai;
18676             app.instrumentationProfileFile = profileFile;
18677             app.instrumentationArguments = arguments;
18678             app.instrumentationWatcher = watcher;
18679             app.instrumentationUiAutomationConnection = uiAutomationConnection;
18680             app.instrumentationResultClass = className;
18681             Binder.restoreCallingIdentity(origId);
18682         }
18683 
18684         return true;
18685     }
18686 
18687     /**
18688      * Report errors that occur while attempting to start Instrumentation.  Always writes the
18689      * error to the logs, but if somebody is watching, send the report there too.  This enables
18690      * the "am" command to report errors with more information.
18691      *
18692      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18693      * @param cn The component name of the instrumentation.
18694      * @param report The error report.
18695      */
reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher, ComponentName cn, String report)18696     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18697             ComponentName cn, String report) {
18698         Slog.w(TAG, report);
18699         if (watcher != null) {
18700             Bundle results = new Bundle();
18701             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18702             results.putString("Error", report);
18703             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18704         }
18705     }
18706 
finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results)18707     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18708         if (app.instrumentationWatcher != null) {
18709             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18710                     app.instrumentationClass, resultCode, results);
18711         }
18712 
18713         // Can't call out of the system process with a lock held, so post a message.
18714         if (app.instrumentationUiAutomationConnection != null) {
18715             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18716                     app.instrumentationUiAutomationConnection).sendToTarget();
18717         }
18718 
18719         app.instrumentationWatcher = null;
18720         app.instrumentationUiAutomationConnection = null;
18721         app.instrumentationClass = null;
18722         app.instrumentationInfo = null;
18723         app.instrumentationProfileFile = null;
18724         app.instrumentationArguments = null;
18725 
18726         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18727                 "finished inst");
18728     }
18729 
finishInstrumentation(IApplicationThread target, int resultCode, Bundle results)18730     public void finishInstrumentation(IApplicationThread target,
18731             int resultCode, Bundle results) {
18732         int userId = UserHandle.getCallingUserId();
18733         // Refuse possible leaked file descriptors
18734         if (results != null && results.hasFileDescriptors()) {
18735             throw new IllegalArgumentException("File descriptors passed in Intent");
18736         }
18737 
18738         synchronized(this) {
18739             ProcessRecord app = getRecordForAppLocked(target);
18740             if (app == null) {
18741                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18742                 return;
18743             }
18744             final long origId = Binder.clearCallingIdentity();
18745             finishInstrumentationLocked(app, resultCode, results);
18746             Binder.restoreCallingIdentity(origId);
18747         }
18748     }
18749 
18750     // =========================================================
18751     // CONFIGURATION
18752     // =========================================================
18753 
getDeviceConfigurationInfo()18754     public ConfigurationInfo getDeviceConfigurationInfo() {
18755         ConfigurationInfo config = new ConfigurationInfo();
18756         synchronized (this) {
18757             config.reqTouchScreen = mConfiguration.touchscreen;
18758             config.reqKeyboardType = mConfiguration.keyboard;
18759             config.reqNavigation = mConfiguration.navigation;
18760             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18761                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18762                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18763             }
18764             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18765                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18766                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18767             }
18768             config.reqGlEsVersion = GL_ES_VERSION;
18769         }
18770         return config;
18771     }
18772 
getFocusedStack()18773     ActivityStack getFocusedStack() {
18774         return mStackSupervisor.getFocusedStack();
18775     }
18776 
18777     @Override
getFocusedStackId()18778     public int getFocusedStackId() throws RemoteException {
18779         ActivityStack focusedStack = getFocusedStack();
18780         if (focusedStack != null) {
18781             return focusedStack.getStackId();
18782         }
18783         return -1;
18784     }
18785 
getConfiguration()18786     public Configuration getConfiguration() {
18787         Configuration ci;
18788         synchronized(this) {
18789             ci = new Configuration(mConfiguration);
18790             ci.userSetLocale = false;
18791         }
18792         return ci;
18793     }
18794 
18795     @Override
suppressResizeConfigChanges(boolean suppress)18796     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18797         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18798         synchronized (this) {
18799             mSuppressResizeConfigChanges = suppress;
18800         }
18801     }
18802 
18803     @Override
moveTasksToFullscreenStack(int fromStackId, boolean onTop)18804     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18805         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18806         if (fromStackId == HOME_STACK_ID) {
18807             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18808         }
18809         synchronized (this) {
18810             final long origId = Binder.clearCallingIdentity();
18811             try {
18812                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18813             } finally {
18814                 Binder.restoreCallingIdentity(origId);
18815             }
18816         }
18817     }
18818 
18819     @Override
updatePersistentConfiguration(Configuration values)18820     public void updatePersistentConfiguration(Configuration values) {
18821         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18822                 "updateConfiguration()");
18823         enforceWriteSettingsPermission("updateConfiguration()");
18824         if (values == null) {
18825             throw new NullPointerException("Configuration must not be null");
18826         }
18827 
18828         int userId = UserHandle.getCallingUserId();
18829 
18830         synchronized(this) {
18831             updatePersistentConfigurationLocked(values, userId);
18832         }
18833     }
18834 
updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId)18835     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18836         final long origId = Binder.clearCallingIdentity();
18837         try {
18838             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18839         } finally {
18840             Binder.restoreCallingIdentity(origId);
18841         }
18842     }
18843 
updateFontScaleIfNeeded(@serIdInt int userId)18844     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18845         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18846                 FONT_SCALE, 1.0f, userId);
18847         if (mConfiguration.fontScale != scaleFactor) {
18848             final Configuration configuration = mWindowManager.computeNewConfiguration();
18849             configuration.fontScale = scaleFactor;
18850             synchronized (this) {
18851                 updatePersistentConfigurationLocked(configuration, userId);
18852             }
18853         }
18854     }
18855 
enforceWriteSettingsPermission(String func)18856     private void enforceWriteSettingsPermission(String func) {
18857         int uid = Binder.getCallingUid();
18858         if (uid == Process.ROOT_UID) {
18859             return;
18860         }
18861 
18862         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18863                 Settings.getPackageNameForUid(mContext, uid), false)) {
18864             return;
18865         }
18866 
18867         String msg = "Permission Denial: " + func + " from pid="
18868                 + Binder.getCallingPid()
18869                 + ", uid=" + uid
18870                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18871         Slog.w(TAG, msg);
18872         throw new SecurityException(msg);
18873     }
18874 
updateConfiguration(Configuration values)18875     public void updateConfiguration(Configuration values) {
18876         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18877                 "updateConfiguration()");
18878 
18879         synchronized(this) {
18880             if (values == null && mWindowManager != null) {
18881                 // sentinel: fetch the current configuration from the window manager
18882                 values = mWindowManager.computeNewConfiguration();
18883             }
18884 
18885             if (mWindowManager != null) {
18886                 mProcessList.applyDisplaySize(mWindowManager);
18887             }
18888 
18889             final long origId = Binder.clearCallingIdentity();
18890             if (values != null) {
18891                 Settings.System.clearConfiguration(values);
18892             }
18893             updateConfigurationLocked(values, null, false);
18894             Binder.restoreCallingIdentity(origId);
18895         }
18896     }
18897 
updateUserConfigurationLocked()18898     void updateUserConfigurationLocked() {
18899         Configuration configuration = new Configuration(mConfiguration);
18900         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18901                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18902         updateConfigurationLocked(configuration, null, false);
18903     }
18904 
updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean initLocale)18905     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18906             boolean initLocale) {
18907         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18908     }
18909 
updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean initLocale, boolean deferResume)18910     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18911             boolean initLocale, boolean deferResume) {
18912         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18913         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18914                 UserHandle.USER_NULL, deferResume);
18915     }
18916 
18917     // To cache the list of supported system locales
18918     private String[] mSupportedSystemLocales = null;
18919 
18920     /**
18921      * Do either or both things: (1) change the current configuration, and (2)
18922      * make sure the given activity is running with the (now) current
18923      * configuration.  Returns true if the activity has been left running, or
18924      * false if <var>starting</var> is being destroyed to match the new
18925      * configuration.
18926      *
18927      * @param userId is only used when persistent parameter is set to true to persist configuration
18928      *               for that particular user
18929      */
updateConfigurationLocked(Configuration values, ActivityRecord starting, boolean initLocale, boolean persistent, int userId, boolean deferResume)18930     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18931             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
18932         int changes = 0;
18933 
18934         if (mWindowManager != null) {
18935             mWindowManager.deferSurfaceLayout();
18936         }
18937         if (values != null) {
18938             Configuration newConfig = new Configuration(mConfiguration);
18939             changes = newConfig.updateFrom(values);
18940             if (changes != 0) {
18941                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
18942                         "Updating configuration to: " + values);
18943 
18944                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
18945 
18946                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
18947                     final LocaleList locales = values.getLocales();
18948                     int bestLocaleIndex = 0;
18949                     if (locales.size() > 1) {
18950                         if (mSupportedSystemLocales == null) {
18951                             mSupportedSystemLocales =
18952                                     Resources.getSystem().getAssets().getLocales();
18953                         }
18954                         bestLocaleIndex = Math.max(0,
18955                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
18956                     }
18957                     SystemProperties.set("persist.sys.locale",
18958                             locales.get(bestLocaleIndex).toLanguageTag());
18959                     LocaleList.setDefault(locales, bestLocaleIndex);
18960                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
18961                             locales.get(bestLocaleIndex)));
18962                 }
18963 
18964                 mConfigurationSeq++;
18965                 if (mConfigurationSeq <= 0) {
18966                     mConfigurationSeq = 1;
18967                 }
18968                 newConfig.seq = mConfigurationSeq;
18969                 mConfiguration = newConfig;
18970                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
18971                 mUsageStatsService.reportConfigurationChange(newConfig,
18972                         mUserController.getCurrentUserIdLocked());
18973                 //mUsageStatsService.noteStartConfig(newConfig);
18974 
18975                 final Configuration configCopy = new Configuration(mConfiguration);
18976 
18977                 // TODO: If our config changes, should we auto dismiss any currently
18978                 // showing dialogs?
18979                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
18980 
18981                 AttributeCache ac = AttributeCache.instance();
18982                 if (ac != null) {
18983                     ac.updateConfiguration(configCopy);
18984                 }
18985 
18986                 // Make sure all resources in our process are updated
18987                 // right now, so that anyone who is going to retrieve
18988                 // resource values after we return will be sure to get
18989                 // the new ones.  This is especially important during
18990                 // boot, where the first config change needs to guarantee
18991                 // all resources have that config before following boot
18992                 // code is executed.
18993                 mSystemThread.applyConfigurationToResources(configCopy);
18994 
18995                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
18996                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
18997                     msg.obj = new Configuration(configCopy);
18998                     msg.arg1 = userId;
18999                     mHandler.sendMessage(msg);
19000                 }
19001 
19002                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19003                 if (isDensityChange) {
19004                     // Reset the unsupported display size dialog.
19005                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19006 
19007                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19008                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19009                 }
19010 
19011                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19012                     ProcessRecord app = mLruProcesses.get(i);
19013                     try {
19014                         if (app.thread != null) {
19015                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19016                                     + app.processName + " new config " + mConfiguration);
19017                             app.thread.scheduleConfigurationChanged(configCopy);
19018                         }
19019                     } catch (Exception e) {
19020                     }
19021                 }
19022                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19023                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19024                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
19025                         | Intent.FLAG_RECEIVER_FOREGROUND);
19026                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19027                         null, AppOpsManager.OP_NONE, null, false, false,
19028                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19029                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19030                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19031                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19032                     if (!mProcessesReady) {
19033                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19034                     }
19035                     broadcastIntentLocked(null, null, intent,
19036                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19037                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19038                 }
19039             }
19040             // Update the configuration with WM first and check if any of the stacks need to be
19041             // resized due to the configuration change. If so, resize the stacks now and do any
19042             // relaunches if necessary. This way we don't need to relaunch again below in
19043             // ensureActivityConfigurationLocked().
19044             if (mWindowManager != null) {
19045                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19046                 if (resizedStacks != null) {
19047                     for (int stackId : resizedStacks) {
19048                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19049                         mStackSupervisor.resizeStackLocked(
19050                                 stackId, newBounds, null, null, false, false, deferResume);
19051                     }
19052                 }
19053             }
19054         }
19055 
19056         boolean kept = true;
19057         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19058         // mainStack is null during startup.
19059         if (mainStack != null) {
19060             if (changes != 0 && starting == null) {
19061                 // If the configuration changed, and the caller is not already
19062                 // in the process of starting an activity, then find the top
19063                 // activity to check if its configuration needs to change.
19064                 starting = mainStack.topRunningActivityLocked();
19065             }
19066 
19067             if (starting != null) {
19068                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19069                 // And we need to make sure at this point that all other activities
19070                 // are made visible with the correct configuration.
19071                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19072                         !PRESERVE_WINDOWS);
19073             }
19074         }
19075         if (mWindowManager != null) {
19076             mWindowManager.continueSurfaceLayout();
19077         }
19078         return kept;
19079     }
19080 
19081     /**
19082      * Decide based on the configuration whether we should shouw the ANR,
19083      * crash, etc dialogs.  The idea is that if there is no affordence to
19084      * press the on-screen buttons, or the user experience would be more
19085      * greatly impacted than the crash itself, we shouldn't show the dialog.
19086      *
19087      * A thought: SystemUI might also want to get told about this, the Power
19088      * dialog / global actions also might want different behaviors.
19089      */
shouldShowDialogs(Configuration config, boolean inVrMode)19090     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19091         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19092                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19093                                    && config.navigation == Configuration.NAVIGATION_NONAV);
19094         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19095         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19096                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19097         return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19098     }
19099 
19100     @Override
shouldUpRecreateTask(IBinder token, String destAffinity)19101     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19102         synchronized (this) {
19103             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19104             if (srec != null) {
19105                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19106             }
19107         }
19108         return false;
19109     }
19110 
navigateUpTo(IBinder token, Intent destIntent, int resultCode, Intent resultData)19111     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19112             Intent resultData) {
19113 
19114         synchronized (this) {
19115             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19116             if (r != null) {
19117                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19118             }
19119             return false;
19120         }
19121     }
19122 
getLaunchedFromUid(IBinder activityToken)19123     public int getLaunchedFromUid(IBinder activityToken) {
19124         ActivityRecord srec;
19125         synchronized (this) {
19126             srec = ActivityRecord.forTokenLocked(activityToken);
19127         }
19128         if (srec == null) {
19129             return -1;
19130         }
19131         return srec.launchedFromUid;
19132     }
19133 
getLaunchedFromPackage(IBinder activityToken)19134     public String getLaunchedFromPackage(IBinder activityToken) {
19135         ActivityRecord srec;
19136         synchronized (this) {
19137             srec = ActivityRecord.forTokenLocked(activityToken);
19138         }
19139         if (srec == null) {
19140             return null;
19141         }
19142         return srec.launchedFromPackage;
19143     }
19144 
19145     // =========================================================
19146     // LIFETIME MANAGEMENT
19147     // =========================================================
19148 
19149     // Returns which broadcast queue the app is the current [or imminent] receiver
19150     // on, or 'null' if the app is not an active broadcast recipient.
isReceivingBroadcast(ProcessRecord app)19151     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19152         BroadcastRecord r = app.curReceiver;
19153         if (r != null) {
19154             return r.queue;
19155         }
19156 
19157         // It's not the current receiver, but it might be starting up to become one
19158         synchronized (this) {
19159             for (BroadcastQueue queue : mBroadcastQueues) {
19160                 r = queue.mPendingBroadcast;
19161                 if (r != null && r.curApp == app) {
19162                     // found it; report which queue it's in
19163                     return queue;
19164                 }
19165             }
19166         }
19167 
19168         return null;
19169     }
19170 
startAssociationLocked(int sourceUid, String sourceProcess, int sourceState, int targetUid, ComponentName targetComponent, String targetProcess)19171     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19172             int targetUid, ComponentName targetComponent, String targetProcess) {
19173         if (!mTrackingAssociations) {
19174             return null;
19175         }
19176         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19177                 = mAssociations.get(targetUid);
19178         if (components == null) {
19179             components = new ArrayMap<>();
19180             mAssociations.put(targetUid, components);
19181         }
19182         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19183         if (sourceUids == null) {
19184             sourceUids = new SparseArray<>();
19185             components.put(targetComponent, sourceUids);
19186         }
19187         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19188         if (sourceProcesses == null) {
19189             sourceProcesses = new ArrayMap<>();
19190             sourceUids.put(sourceUid, sourceProcesses);
19191         }
19192         Association ass = sourceProcesses.get(sourceProcess);
19193         if (ass == null) {
19194             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19195                     targetProcess);
19196             sourceProcesses.put(sourceProcess, ass);
19197         }
19198         ass.mCount++;
19199         ass.mNesting++;
19200         if (ass.mNesting == 1) {
19201             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19202             ass.mLastState = sourceState;
19203         }
19204         return ass;
19205     }
19206 
stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid, ComponentName targetComponent)19207     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19208             ComponentName targetComponent) {
19209         if (!mTrackingAssociations) {
19210             return;
19211         }
19212         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19213                 = mAssociations.get(targetUid);
19214         if (components == null) {
19215             return;
19216         }
19217         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19218         if (sourceUids == null) {
19219             return;
19220         }
19221         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19222         if (sourceProcesses == null) {
19223             return;
19224         }
19225         Association ass = sourceProcesses.get(sourceProcess);
19226         if (ass == null || ass.mNesting <= 0) {
19227             return;
19228         }
19229         ass.mNesting--;
19230         if (ass.mNesting == 0) {
19231             long uptime = SystemClock.uptimeMillis();
19232             ass.mTime += uptime - ass.mStartTime;
19233             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19234                     += uptime - ass.mLastStateUptime;
19235             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19236         }
19237     }
19238 
noteUidProcessState(final int uid, final int state)19239     private void noteUidProcessState(final int uid, final int state) {
19240         mBatteryStatsService.noteUidProcessState(uid, state);
19241         if (mTrackingAssociations) {
19242             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19243                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19244                         = mAssociations.valueAt(i1);
19245                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19246                     SparseArray<ArrayMap<String, Association>> sourceUids
19247                             = targetComponents.valueAt(i2);
19248                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19249                     if (sourceProcesses != null) {
19250                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19251                             Association ass = sourceProcesses.valueAt(i4);
19252                             if (ass.mNesting >= 1) {
19253                                 // currently associated
19254                                 long uptime = SystemClock.uptimeMillis();
19255                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19256                                         += uptime - ass.mLastStateUptime;
19257                                 ass.mLastState = state;
19258                                 ass.mLastStateUptime = uptime;
19259                             }
19260                         }
19261                     }
19262                 }
19263             }
19264         }
19265     }
19266 
computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, long now)19267     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19268             boolean doingAll, long now) {
19269         if (mAdjSeq == app.adjSeq) {
19270             // This adjustment has already been computed.
19271             return app.curRawAdj;
19272         }
19273 
19274         if (app.thread == null) {
19275             app.adjSeq = mAdjSeq;
19276             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19277             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19278             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19279         }
19280 
19281         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19282         app.adjSource = null;
19283         app.adjTarget = null;
19284         app.empty = false;
19285         app.cached = false;
19286 
19287         final int activitiesSize = app.activities.size();
19288 
19289         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19290             // The max adjustment doesn't allow this app to be anything
19291             // below foreground, so it is not worth doing work for it.
19292             app.adjType = "fixed";
19293             app.adjSeq = mAdjSeq;
19294             app.curRawAdj = app.maxAdj;
19295             app.foregroundActivities = false;
19296             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19297             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19298             // System processes can do UI, and when they do we want to have
19299             // them trim their memory after the user leaves the UI.  To
19300             // facilitate this, here we need to determine whether or not it
19301             // is currently showing UI.
19302             app.systemNoUi = true;
19303             if (app == TOP_APP) {
19304                 app.systemNoUi = false;
19305                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19306                 app.adjType = "pers-top-activity";
19307             } else if (app.hasTopUi) {
19308                 app.systemNoUi = false;
19309                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19310                 app.adjType = "pers-top-ui";
19311             } else if (activitiesSize > 0) {
19312                 for (int j = 0; j < activitiesSize; j++) {
19313                     final ActivityRecord r = app.activities.get(j);
19314                     if (r.visible) {
19315                         app.systemNoUi = false;
19316                     }
19317                 }
19318             }
19319             if (!app.systemNoUi) {
19320                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19321             }
19322             return (app.curAdj=app.maxAdj);
19323         }
19324 
19325         app.systemNoUi = false;
19326 
19327         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19328 
19329         // Determine the importance of the process, starting with most
19330         // important to least, and assign an appropriate OOM adjustment.
19331         int adj;
19332         int schedGroup;
19333         int procState;
19334         boolean foregroundActivities = false;
19335         BroadcastQueue queue;
19336         if (app == TOP_APP) {
19337             // The last app on the list is the foreground app.
19338             adj = ProcessList.FOREGROUND_APP_ADJ;
19339             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19340             app.adjType = "top-activity";
19341             foregroundActivities = true;
19342             procState = PROCESS_STATE_CUR_TOP;
19343         } else if (app.instrumentationClass != null) {
19344             // Don't want to kill running instrumentation.
19345             adj = ProcessList.FOREGROUND_APP_ADJ;
19346             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19347             app.adjType = "instrumentation";
19348             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19349         } else if ((queue = isReceivingBroadcast(app)) != null) {
19350             // An app that is currently receiving a broadcast also
19351             // counts as being in the foreground for OOM killer purposes.
19352             // It's placed in a sched group based on the nature of the
19353             // broadcast as reflected by which queue it's active in.
19354             adj = ProcessList.FOREGROUND_APP_ADJ;
19355             schedGroup = (queue == mFgBroadcastQueue)
19356                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19357             app.adjType = "broadcast";
19358             procState = ActivityManager.PROCESS_STATE_RECEIVER;
19359         } else if (app.executingServices.size() > 0) {
19360             // An app that is currently executing a service callback also
19361             // counts as being in the foreground.
19362             adj = ProcessList.FOREGROUND_APP_ADJ;
19363             schedGroup = app.execServicesFg ?
19364                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19365             app.adjType = "exec-service";
19366             procState = ActivityManager.PROCESS_STATE_SERVICE;
19367             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19368         } else {
19369             // As far as we know the process is empty.  We may change our mind later.
19370             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19371             // At this point we don't actually know the adjustment.  Use the cached adj
19372             // value that the caller wants us to.
19373             adj = cachedAdj;
19374             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19375             app.cached = true;
19376             app.empty = true;
19377             app.adjType = "cch-empty";
19378         }
19379 
19380         // Examine all activities if not already foreground.
19381         if (!foregroundActivities && activitiesSize > 0) {
19382             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19383             for (int j = 0; j < activitiesSize; j++) {
19384                 final ActivityRecord r = app.activities.get(j);
19385                 if (r.app != app) {
19386                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19387                             + " instead of expected " + app);
19388                     if (r.app == null || (r.app.uid == app.uid)) {
19389                         // Only fix things up when they look sane
19390                         r.app = app;
19391                     } else {
19392                         continue;
19393                     }
19394                 }
19395                 if (r.visible) {
19396                     // App has a visible activity; only upgrade adjustment.
19397                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19398                         adj = ProcessList.VISIBLE_APP_ADJ;
19399                         app.adjType = "visible";
19400                     }
19401                     if (procState > PROCESS_STATE_CUR_TOP) {
19402                         procState = PROCESS_STATE_CUR_TOP;
19403                     }
19404                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19405                     app.cached = false;
19406                     app.empty = false;
19407                     foregroundActivities = true;
19408                     if (r.task != null && minLayer > 0) {
19409                         final int layer = r.task.mLayerRank;
19410                         if (layer >= 0 && minLayer > layer) {
19411                             minLayer = layer;
19412                         }
19413                     }
19414                     break;
19415                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19416                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19417                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19418                         app.adjType = "pausing";
19419                     }
19420                     if (procState > PROCESS_STATE_CUR_TOP) {
19421                         procState = PROCESS_STATE_CUR_TOP;
19422                     }
19423                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19424                     app.cached = false;
19425                     app.empty = false;
19426                     foregroundActivities = true;
19427                 } else if (r.state == ActivityState.STOPPING) {
19428                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19429                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19430                         app.adjType = "stopping";
19431                     }
19432                     // For the process state, we will at this point consider the
19433                     // process to be cached.  It will be cached either as an activity
19434                     // or empty depending on whether the activity is finishing.  We do
19435                     // this so that we can treat the process as cached for purposes of
19436                     // memory trimming (determing current memory level, trim command to
19437                     // send to process) since there can be an arbitrary number of stopping
19438                     // processes and they should soon all go into the cached state.
19439                     if (!r.finishing) {
19440                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19441                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19442                         }
19443                     }
19444                     app.cached = false;
19445                     app.empty = false;
19446                     foregroundActivities = true;
19447                 } else {
19448                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19449                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19450                         app.adjType = "cch-act";
19451                     }
19452                 }
19453             }
19454             if (adj == ProcessList.VISIBLE_APP_ADJ) {
19455                 adj += minLayer;
19456             }
19457         }
19458 
19459         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19460                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19461             if (app.foregroundServices) {
19462                 // The user is aware of this app, so make it visible.
19463                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19464                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19465                 app.cached = false;
19466                 app.adjType = "fg-service";
19467                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19468             } else if (app.forcingToForeground != null) {
19469                 // The user is aware of this app, so make it visible.
19470                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19471                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19472                 app.cached = false;
19473                 app.adjType = "force-fg";
19474                 app.adjSource = app.forcingToForeground;
19475                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19476             }
19477         }
19478 
19479         if (app == mHeavyWeightProcess) {
19480             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19481                 // We don't want to kill the current heavy-weight process.
19482                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19483                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19484                 app.cached = false;
19485                 app.adjType = "heavy";
19486             }
19487             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19488                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19489             }
19490         }
19491 
19492         if (app == mHomeProcess) {
19493             if (adj > ProcessList.HOME_APP_ADJ) {
19494                 // This process is hosting what we currently consider to be the
19495                 // home app, so we don't want to let it go into the background.
19496                 adj = ProcessList.HOME_APP_ADJ;
19497                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19498                 app.cached = false;
19499                 app.adjType = "home";
19500             }
19501             if (procState > ActivityManager.PROCESS_STATE_HOME) {
19502                 procState = ActivityManager.PROCESS_STATE_HOME;
19503             }
19504         }
19505 
19506         if (app == mPreviousProcess && app.activities.size() > 0) {
19507             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19508                 // This was the previous process that showed UI to the user.
19509                 // We want to try to keep it around more aggressively, to give
19510                 // a good experience around switching between two apps.
19511                 adj = ProcessList.PREVIOUS_APP_ADJ;
19512                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19513                 app.cached = false;
19514                 app.adjType = "previous";
19515             }
19516             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19517                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19518             }
19519         }
19520 
19521         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19522                 + " reason=" + app.adjType);
19523 
19524         // By default, we use the computed adjustment.  It may be changed if
19525         // there are applications dependent on our services or providers, but
19526         // this gives us a baseline and makes sure we don't get into an
19527         // infinite recursion.
19528         app.adjSeq = mAdjSeq;
19529         app.curRawAdj = adj;
19530         app.hasStartedServices = false;
19531 
19532         if (mBackupTarget != null && app == mBackupTarget.app) {
19533             // If possible we want to avoid killing apps while they're being backed up
19534             if (adj > ProcessList.BACKUP_APP_ADJ) {
19535                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19536                 adj = ProcessList.BACKUP_APP_ADJ;
19537                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19538                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19539                 }
19540                 app.adjType = "backup";
19541                 app.cached = false;
19542             }
19543             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19544                 procState = ActivityManager.PROCESS_STATE_BACKUP;
19545             }
19546         }
19547 
19548         boolean mayBeTop = false;
19549 
19550         for (int is = app.services.size()-1;
19551                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19552                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19553                         || procState > ActivityManager.PROCESS_STATE_TOP);
19554                 is--) {
19555             ServiceRecord s = app.services.valueAt(is);
19556             if (s.startRequested) {
19557                 app.hasStartedServices = true;
19558                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19559                     procState = ActivityManager.PROCESS_STATE_SERVICE;
19560                 }
19561                 if (app.hasShownUi && app != mHomeProcess) {
19562                     // If this process has shown some UI, let it immediately
19563                     // go to the LRU list because it may be pretty heavy with
19564                     // UI stuff.  We'll tag it with a label just to help
19565                     // debug and understand what is going on.
19566                     if (adj > ProcessList.SERVICE_ADJ) {
19567                         app.adjType = "cch-started-ui-services";
19568                     }
19569                 } else {
19570                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19571                         // This service has seen some activity within
19572                         // recent memory, so we will keep its process ahead
19573                         // of the background processes.
19574                         if (adj > ProcessList.SERVICE_ADJ) {
19575                             adj = ProcessList.SERVICE_ADJ;
19576                             app.adjType = "started-services";
19577                             app.cached = false;
19578                         }
19579                     }
19580                     // If we have let the service slide into the background
19581                     // state, still have some text describing what it is doing
19582                     // even though the service no longer has an impact.
19583                     if (adj > ProcessList.SERVICE_ADJ) {
19584                         app.adjType = "cch-started-services";
19585                     }
19586                 }
19587             }
19588 
19589             for (int conni = s.connections.size()-1;
19590                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19591                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19592                             || procState > ActivityManager.PROCESS_STATE_TOP);
19593                     conni--) {
19594                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19595                 for (int i = 0;
19596                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19597                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19598                                 || procState > ActivityManager.PROCESS_STATE_TOP);
19599                         i++) {
19600                     // XXX should compute this based on the max of
19601                     // all connected clients.
19602                     ConnectionRecord cr = clist.get(i);
19603                     if (cr.binding.client == app) {
19604                         // Binding to ourself is not interesting.
19605                         continue;
19606                     }
19607 
19608                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19609                         ProcessRecord client = cr.binding.client;
19610                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
19611                                 TOP_APP, doingAll, now);
19612                         int clientProcState = client.curProcState;
19613                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19614                             // If the other app is cached for any reason, for purposes here
19615                             // we are going to consider it empty.  The specific cached state
19616                             // doesn't propagate except under certain conditions.
19617                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19618                         }
19619                         String adjType = null;
19620                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19621                             // Not doing bind OOM management, so treat
19622                             // this guy more like a started service.
19623                             if (app.hasShownUi && app != mHomeProcess) {
19624                                 // If this process has shown some UI, let it immediately
19625                                 // go to the LRU list because it may be pretty heavy with
19626                                 // UI stuff.  We'll tag it with a label just to help
19627                                 // debug and understand what is going on.
19628                                 if (adj > clientAdj) {
19629                                     adjType = "cch-bound-ui-services";
19630                                 }
19631                                 app.cached = false;
19632                                 clientAdj = adj;
19633                                 clientProcState = procState;
19634                             } else {
19635                                 if (now >= (s.lastActivity
19636                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19637                                     // This service has not seen activity within
19638                                     // recent memory, so allow it to drop to the
19639                                     // LRU list if there is no other reason to keep
19640                                     // it around.  We'll also tag it with a label just
19641                                     // to help debug and undertand what is going on.
19642                                     if (adj > clientAdj) {
19643                                         adjType = "cch-bound-services";
19644                                     }
19645                                     clientAdj = adj;
19646                                 }
19647                             }
19648                         }
19649                         if (adj > clientAdj) {
19650                             // If this process has recently shown UI, and
19651                             // the process that is binding to it is less
19652                             // important than being visible, then we don't
19653                             // care about the binding as much as we care
19654                             // about letting this process get into the LRU
19655                             // list to be killed and restarted if needed for
19656                             // memory.
19657                             if (app.hasShownUi && app != mHomeProcess
19658                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19659                                 adjType = "cch-bound-ui-services";
19660                             } else {
19661                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19662                                         |Context.BIND_IMPORTANT)) != 0) {
19663                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19664                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19665                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19666                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19667                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19668                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19669                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19670                                     adj = clientAdj;
19671                                 } else {
19672                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19673                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19674                                     }
19675                                 }
19676                                 if (!client.cached) {
19677                                     app.cached = false;
19678                                 }
19679                                 adjType = "service";
19680                             }
19681                         }
19682                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19683                             // This will treat important bound services identically to
19684                             // the top app, which may behave differently than generic
19685                             // foreground work.
19686                             if (client.curSchedGroup > schedGroup) {
19687                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19688                                     schedGroup = client.curSchedGroup;
19689                                 } else {
19690                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19691                                 }
19692                             }
19693                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19694                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19695                                     // Special handling of clients who are in the top state.
19696                                     // We *may* want to consider this process to be in the
19697                                     // top state as well, but only if there is not another
19698                                     // reason for it to be running.  Being on the top is a
19699                                     // special state, meaning you are specifically running
19700                                     // for the current top app.  If the process is already
19701                                     // running in the background for some other reason, it
19702                                     // is more important to continue considering it to be
19703                                     // in the background state.
19704                                     mayBeTop = true;
19705                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19706                                 } else {
19707                                     // Special handling for above-top states (persistent
19708                                     // processes).  These should not bring the current process
19709                                     // into the top state, since they are not on top.  Instead
19710                                     // give them the best state after that.
19711                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19712                                         clientProcState =
19713                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19714                                     } else if (mWakefulness
19715                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19716                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19717                                                     != 0) {
19718                                         clientProcState =
19719                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19720                                     } else {
19721                                         clientProcState =
19722                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19723                                     }
19724                                 }
19725                             }
19726                         } else {
19727                             if (clientProcState <
19728                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19729                                 clientProcState =
19730                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19731                             }
19732                         }
19733                         if (procState > clientProcState) {
19734                             procState = clientProcState;
19735                         }
19736                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19737                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19738                             app.pendingUiClean = true;
19739                         }
19740                         if (adjType != null) {
19741                             app.adjType = adjType;
19742                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19743                                     .REASON_SERVICE_IN_USE;
19744                             app.adjSource = cr.binding.client;
19745                             app.adjSourceProcState = clientProcState;
19746                             app.adjTarget = s.name;
19747                         }
19748                     }
19749                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19750                         app.treatLikeActivity = true;
19751                     }
19752                     final ActivityRecord a = cr.activity;
19753                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19754                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19755                             (a.visible || a.state == ActivityState.RESUMED ||
19756                              a.state == ActivityState.PAUSING)) {
19757                             adj = ProcessList.FOREGROUND_APP_ADJ;
19758                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19759                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19760                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19761                                 } else {
19762                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19763                                 }
19764                             }
19765                             app.cached = false;
19766                             app.adjType = "service";
19767                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19768                                     .REASON_SERVICE_IN_USE;
19769                             app.adjSource = a;
19770                             app.adjSourceProcState = procState;
19771                             app.adjTarget = s.name;
19772                         }
19773                     }
19774                 }
19775             }
19776         }
19777 
19778         for (int provi = app.pubProviders.size()-1;
19779                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19780                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19781                         || procState > ActivityManager.PROCESS_STATE_TOP);
19782                 provi--) {
19783             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19784             for (int i = cpr.connections.size()-1;
19785                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19786                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19787                             || procState > ActivityManager.PROCESS_STATE_TOP);
19788                     i--) {
19789                 ContentProviderConnection conn = cpr.connections.get(i);
19790                 ProcessRecord client = conn.client;
19791                 if (client == app) {
19792                     // Being our own client is not interesting.
19793                     continue;
19794                 }
19795                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19796                 int clientProcState = client.curProcState;
19797                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19798                     // If the other app is cached for any reason, for purposes here
19799                     // we are going to consider it empty.
19800                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19801                 }
19802                 if (adj > clientAdj) {
19803                     if (app.hasShownUi && app != mHomeProcess
19804                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19805                         app.adjType = "cch-ui-provider";
19806                     } else {
19807                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19808                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19809                         app.adjType = "provider";
19810                     }
19811                     app.cached &= client.cached;
19812                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19813                             .REASON_PROVIDER_IN_USE;
19814                     app.adjSource = client;
19815                     app.adjSourceProcState = clientProcState;
19816                     app.adjTarget = cpr.name;
19817                 }
19818                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19819                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19820                         // Special handling of clients who are in the top state.
19821                         // We *may* want to consider this process to be in the
19822                         // top state as well, but only if there is not another
19823                         // reason for it to be running.  Being on the top is a
19824                         // special state, meaning you are specifically running
19825                         // for the current top app.  If the process is already
19826                         // running in the background for some other reason, it
19827                         // is more important to continue considering it to be
19828                         // in the background state.
19829                         mayBeTop = true;
19830                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19831                     } else {
19832                         // Special handling for above-top states (persistent
19833                         // processes).  These should not bring the current process
19834                         // into the top state, since they are not on top.  Instead
19835                         // give them the best state after that.
19836                         clientProcState =
19837                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19838                     }
19839                 }
19840                 if (procState > clientProcState) {
19841                     procState = clientProcState;
19842                 }
19843                 if (client.curSchedGroup > schedGroup) {
19844                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19845                 }
19846             }
19847             // If the provider has external (non-framework) process
19848             // dependencies, ensure that its adjustment is at least
19849             // FOREGROUND_APP_ADJ.
19850             if (cpr.hasExternalProcessHandles()) {
19851                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19852                     adj = ProcessList.FOREGROUND_APP_ADJ;
19853                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19854                     app.cached = false;
19855                     app.adjType = "provider";
19856                     app.adjTarget = cpr.name;
19857                 }
19858                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19859                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19860                 }
19861             }
19862         }
19863 
19864         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19865             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19866                 adj = ProcessList.PREVIOUS_APP_ADJ;
19867                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19868                 app.cached = false;
19869                 app.adjType = "provider";
19870             }
19871             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19872                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19873             }
19874         }
19875 
19876         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19877             // A client of one of our services or providers is in the top state.  We
19878             // *may* want to be in the top state, but not if we are already running in
19879             // the background for some other reason.  For the decision here, we are going
19880             // to pick out a few specific states that we want to remain in when a client
19881             // is top (states that tend to be longer-term) and otherwise allow it to go
19882             // to the top state.
19883             switch (procState) {
19884                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19885                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19886                 case ActivityManager.PROCESS_STATE_SERVICE:
19887                     // These all are longer-term states, so pull them up to the top
19888                     // of the background states, but not all the way to the top state.
19889                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19890                     break;
19891                 default:
19892                     // Otherwise, top is a better choice, so take it.
19893                     procState = ActivityManager.PROCESS_STATE_TOP;
19894                     break;
19895             }
19896         }
19897 
19898         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19899             if (app.hasClientActivities) {
19900                 // This is a cached process, but with client activities.  Mark it so.
19901                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19902                 app.adjType = "cch-client-act";
19903             } else if (app.treatLikeActivity) {
19904                 // This is a cached process, but somebody wants us to treat it like it has
19905                 // an activity, okay!
19906                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19907                 app.adjType = "cch-as-act";
19908             }
19909         }
19910 
19911         if (adj == ProcessList.SERVICE_ADJ) {
19912             if (doingAll) {
19913                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19914                 mNewNumServiceProcs++;
19915                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19916                 if (!app.serviceb) {
19917                     // This service isn't far enough down on the LRU list to
19918                     // normally be a B service, but if we are low on RAM and it
19919                     // is large we want to force it down since we would prefer to
19920                     // keep launcher over it.
19921                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19922                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
19923                         app.serviceHighRam = true;
19924                         app.serviceb = true;
19925                         //Slog.i(TAG, "ADJ " + app + " high ram!");
19926                     } else {
19927                         mNewNumAServiceProcs++;
19928                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
19929                     }
19930                 } else {
19931                     app.serviceHighRam = false;
19932                 }
19933             }
19934             if (app.serviceb) {
19935                 adj = ProcessList.SERVICE_B_ADJ;
19936             }
19937         }
19938 
19939         app.curRawAdj = adj;
19940 
19941         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
19942         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
19943         if (adj > app.maxAdj) {
19944             adj = app.maxAdj;
19945             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
19946                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19947             }
19948         }
19949 
19950         // Do final modification to adj.  Everything we do between here and applying
19951         // the final setAdj must be done in this function, because we will also use
19952         // it when computing the final cached adj later.  Note that we don't need to
19953         // worry about this for max adj above, since max adj will always be used to
19954         // keep it out of the cached vaues.
19955         app.curAdj = app.modifyRawOomAdj(adj);
19956         app.curSchedGroup = schedGroup;
19957         app.curProcState = procState;
19958         app.foregroundActivities = foregroundActivities;
19959 
19960         return app.curRawAdj;
19961     }
19962 
19963     /**
19964      * Record new PSS sample for a process.
19965      */
recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss, long now)19966     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
19967             long now) {
19968         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
19969                 swapPss * 1024);
19970         proc.lastPssTime = now;
19971         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
19972         if (DEBUG_PSS) Slog.d(TAG_PSS,
19973                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
19974                 + " state=" + ProcessList.makeProcStateString(procState));
19975         if (proc.initialIdlePss == 0) {
19976             proc.initialIdlePss = pss;
19977         }
19978         proc.lastPss = pss;
19979         proc.lastSwapPss = swapPss;
19980         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
19981             proc.lastCachedPss = pss;
19982             proc.lastCachedSwapPss = swapPss;
19983         }
19984 
19985         final SparseArray<Pair<Long, String>> watchUids
19986                 = mMemWatchProcesses.getMap().get(proc.processName);
19987         Long check = null;
19988         if (watchUids != null) {
19989             Pair<Long, String> val = watchUids.get(proc.uid);
19990             if (val == null) {
19991                 val = watchUids.get(0);
19992             }
19993             if (val != null) {
19994                 check = val.first;
19995             }
19996         }
19997         if (check != null) {
19998             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
19999                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20000                 if (!isDebuggable) {
20001                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20002                         isDebuggable = true;
20003                     }
20004                 }
20005                 if (isDebuggable) {
20006                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20007                     final ProcessRecord myProc = proc;
20008                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
20009                     mMemWatchDumpProcName = proc.processName;
20010                     mMemWatchDumpFile = heapdumpFile.toString();
20011                     mMemWatchDumpPid = proc.pid;
20012                     mMemWatchDumpUid = proc.uid;
20013                     BackgroundThread.getHandler().post(new Runnable() {
20014                         @Override
20015                         public void run() {
20016                             revokeUriPermission(ActivityThread.currentActivityThread()
20017                                             .getApplicationThread(),
20018                                     DumpHeapActivity.JAVA_URI,
20019                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
20020                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20021                                     UserHandle.myUserId());
20022                             ParcelFileDescriptor fd = null;
20023                             try {
20024                                 heapdumpFile.delete();
20025                                 fd = ParcelFileDescriptor.open(heapdumpFile,
20026                                         ParcelFileDescriptor.MODE_CREATE |
20027                                                 ParcelFileDescriptor.MODE_TRUNCATE |
20028                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
20029                                                 ParcelFileDescriptor.MODE_APPEND);
20030                                 IApplicationThread thread = myProc.thread;
20031                                 if (thread != null) {
20032                                     try {
20033                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
20034                                                 "Requesting dump heap from "
20035                                                 + myProc + " to " + heapdumpFile);
20036                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
20037                                     } catch (RemoteException e) {
20038                                     }
20039                                 }
20040                             } catch (FileNotFoundException e) {
20041                                 e.printStackTrace();
20042                             } finally {
20043                                 if (fd != null) {
20044                                     try {
20045                                         fd.close();
20046                                     } catch (IOException e) {
20047                                     }
20048                                 }
20049                             }
20050                         }
20051                     });
20052                 } else {
20053                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20054                             + ", but debugging not enabled");
20055                 }
20056             }
20057         }
20058     }
20059 
20060     /**
20061      * Schedule PSS collection of a process.
20062      */
requestPssLocked(ProcessRecord proc, int procState)20063     void requestPssLocked(ProcessRecord proc, int procState) {
20064         if (mPendingPssProcesses.contains(proc)) {
20065             return;
20066         }
20067         if (mPendingPssProcesses.size() == 0) {
20068             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20069         }
20070         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20071         proc.pssProcState = procState;
20072         mPendingPssProcesses.add(proc);
20073     }
20074 
20075     /**
20076      * Schedule PSS collection of all processes.
20077      */
requestPssAllProcsLocked(long now, boolean always, boolean memLowered)20078     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20079         if (!always) {
20080             if (now < (mLastFullPssTime +
20081                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20082                 return;
20083             }
20084         }
20085         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20086         mLastFullPssTime = now;
20087         mFullPssPending = true;
20088         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20089         mPendingPssProcesses.clear();
20090         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20091             ProcessRecord app = mLruProcesses.get(i);
20092             if (app.thread == null
20093                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20094                 continue;
20095             }
20096             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20097                 app.pssProcState = app.setProcState;
20098                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20099                         mTestPssMode, isSleepingLocked(), now);
20100                 mPendingPssProcesses.add(app);
20101             }
20102         }
20103         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20104     }
20105 
setTestPssMode(boolean enabled)20106     public void setTestPssMode(boolean enabled) {
20107         synchronized (this) {
20108             mTestPssMode = enabled;
20109             if (enabled) {
20110                 // Whenever we enable the mode, we want to take a snapshot all of current
20111                 // process mem use.
20112                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20113             }
20114         }
20115     }
20116 
20117     /**
20118      * Ask a given process to GC right now.
20119      */
performAppGcLocked(ProcessRecord app)20120     final void performAppGcLocked(ProcessRecord app) {
20121         try {
20122             app.lastRequestedGc = SystemClock.uptimeMillis();
20123             if (app.thread != null) {
20124                 if (app.reportLowMemory) {
20125                     app.reportLowMemory = false;
20126                     app.thread.scheduleLowMemory();
20127                 } else {
20128                     app.thread.processInBackground();
20129                 }
20130             }
20131         } catch (Exception e) {
20132             // whatever.
20133         }
20134     }
20135 
20136     /**
20137      * Returns true if things are idle enough to perform GCs.
20138      */
canGcNowLocked()20139     private final boolean canGcNowLocked() {
20140         boolean processingBroadcasts = false;
20141         for (BroadcastQueue q : mBroadcastQueues) {
20142             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20143                 processingBroadcasts = true;
20144             }
20145         }
20146         return !processingBroadcasts
20147                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20148     }
20149 
20150     /**
20151      * Perform GCs on all processes that are waiting for it, but only
20152      * if things are idle.
20153      */
performAppGcsLocked()20154     final void performAppGcsLocked() {
20155         final int N = mProcessesToGc.size();
20156         if (N <= 0) {
20157             return;
20158         }
20159         if (canGcNowLocked()) {
20160             while (mProcessesToGc.size() > 0) {
20161                 ProcessRecord proc = mProcessesToGc.remove(0);
20162                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20163                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20164                             <= SystemClock.uptimeMillis()) {
20165                         // To avoid spamming the system, we will GC processes one
20166                         // at a time, waiting a few seconds between each.
20167                         performAppGcLocked(proc);
20168                         scheduleAppGcsLocked();
20169                         return;
20170                     } else {
20171                         // It hasn't been long enough since we last GCed this
20172                         // process...  put it in the list to wait for its time.
20173                         addProcessToGcListLocked(proc);
20174                         break;
20175                     }
20176                 }
20177             }
20178 
20179             scheduleAppGcsLocked();
20180         }
20181     }
20182 
20183     /**
20184      * If all looks good, perform GCs on all processes waiting for them.
20185      */
performAppGcsIfAppropriateLocked()20186     final void performAppGcsIfAppropriateLocked() {
20187         if (canGcNowLocked()) {
20188             performAppGcsLocked();
20189             return;
20190         }
20191         // Still not idle, wait some more.
20192         scheduleAppGcsLocked();
20193     }
20194 
20195     /**
20196      * Schedule the execution of all pending app GCs.
20197      */
scheduleAppGcsLocked()20198     final void scheduleAppGcsLocked() {
20199         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20200 
20201         if (mProcessesToGc.size() > 0) {
20202             // Schedule a GC for the time to the next process.
20203             ProcessRecord proc = mProcessesToGc.get(0);
20204             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20205 
20206             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20207             long now = SystemClock.uptimeMillis();
20208             if (when < (now+GC_TIMEOUT)) {
20209                 when = now + GC_TIMEOUT;
20210             }
20211             mHandler.sendMessageAtTime(msg, when);
20212         }
20213     }
20214 
20215     /**
20216      * Add a process to the array of processes waiting to be GCed.  Keeps the
20217      * list in sorted order by the last GC time.  The process can't already be
20218      * on the list.
20219      */
addProcessToGcListLocked(ProcessRecord proc)20220     final void addProcessToGcListLocked(ProcessRecord proc) {
20221         boolean added = false;
20222         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20223             if (mProcessesToGc.get(i).lastRequestedGc <
20224                     proc.lastRequestedGc) {
20225                 added = true;
20226                 mProcessesToGc.add(i+1, proc);
20227                 break;
20228             }
20229         }
20230         if (!added) {
20231             mProcessesToGc.add(0, proc);
20232         }
20233     }
20234 
20235     /**
20236      * Set up to ask a process to GC itself.  This will either do it
20237      * immediately, or put it on the list of processes to gc the next
20238      * time things are idle.
20239      */
scheduleAppGcLocked(ProcessRecord app)20240     final void scheduleAppGcLocked(ProcessRecord app) {
20241         long now = SystemClock.uptimeMillis();
20242         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20243             return;
20244         }
20245         if (!mProcessesToGc.contains(app)) {
20246             addProcessToGcListLocked(app);
20247             scheduleAppGcsLocked();
20248         }
20249     }
20250 
checkExcessivePowerUsageLocked(boolean doKills)20251     final void checkExcessivePowerUsageLocked(boolean doKills) {
20252         updateCpuStatsNow();
20253 
20254         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20255         boolean doWakeKills = doKills;
20256         boolean doCpuKills = doKills;
20257         if (mLastPowerCheckRealtime == 0) {
20258             doWakeKills = false;
20259         }
20260         if (mLastPowerCheckUptime == 0) {
20261             doCpuKills = false;
20262         }
20263         if (stats.isScreenOn()) {
20264             doWakeKills = false;
20265         }
20266         final long curRealtime = SystemClock.elapsedRealtime();
20267         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20268         final long curUptime = SystemClock.uptimeMillis();
20269         final long uptimeSince = curUptime - mLastPowerCheckUptime;
20270         mLastPowerCheckRealtime = curRealtime;
20271         mLastPowerCheckUptime = curUptime;
20272         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20273             doWakeKills = false;
20274         }
20275         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20276             doCpuKills = false;
20277         }
20278         int i = mLruProcesses.size();
20279         while (i > 0) {
20280             i--;
20281             ProcessRecord app = mLruProcesses.get(i);
20282             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20283                 long wtime;
20284                 synchronized (stats) {
20285                     wtime = stats.getProcessWakeTime(app.info.uid,
20286                             app.pid, curRealtime);
20287                 }
20288                 long wtimeUsed = wtime - app.lastWakeTime;
20289                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20290                 if (DEBUG_POWER) {
20291                     StringBuilder sb = new StringBuilder(128);
20292                     sb.append("Wake for ");
20293                     app.toShortString(sb);
20294                     sb.append(": over ");
20295                     TimeUtils.formatDuration(realtimeSince, sb);
20296                     sb.append(" used ");
20297                     TimeUtils.formatDuration(wtimeUsed, sb);
20298                     sb.append(" (");
20299                     sb.append((wtimeUsed*100)/realtimeSince);
20300                     sb.append("%)");
20301                     Slog.i(TAG_POWER, sb.toString());
20302                     sb.setLength(0);
20303                     sb.append("CPU for ");
20304                     app.toShortString(sb);
20305                     sb.append(": over ");
20306                     TimeUtils.formatDuration(uptimeSince, sb);
20307                     sb.append(" used ");
20308                     TimeUtils.formatDuration(cputimeUsed, sb);
20309                     sb.append(" (");
20310                     sb.append((cputimeUsed*100)/uptimeSince);
20311                     sb.append("%)");
20312                     Slog.i(TAG_POWER, sb.toString());
20313                 }
20314                 // If a process has held a wake lock for more
20315                 // than 50% of the time during this period,
20316                 // that sounds bad.  Kill!
20317                 if (doWakeKills && realtimeSince > 0
20318                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
20319                     synchronized (stats) {
20320                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20321                                 realtimeSince, wtimeUsed);
20322                     }
20323                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20324                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20325                 } else if (doCpuKills && uptimeSince > 0
20326                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
20327                     synchronized (stats) {
20328                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20329                                 uptimeSince, cputimeUsed);
20330                     }
20331                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20332                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20333                 } else {
20334                     app.lastWakeTime = wtime;
20335                     app.lastCpuTime = app.curCpuTime;
20336                 }
20337             }
20338         }
20339     }
20340 
applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now, long nowElapsed)20341     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20342             long nowElapsed) {
20343         boolean success = true;
20344 
20345         if (app.curRawAdj != app.setRawAdj) {
20346             app.setRawAdj = app.curRawAdj;
20347         }
20348 
20349         int changes = 0;
20350 
20351         if (app.curAdj != app.setAdj) {
20352             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20353             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20354                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20355                     + app.adjType);
20356             app.setAdj = app.curAdj;
20357             app.verifiedAdj = ProcessList.INVALID_ADJ;
20358         }
20359 
20360         if (app.setSchedGroup != app.curSchedGroup) {
20361             int oldSchedGroup = app.setSchedGroup;
20362             app.setSchedGroup = app.curSchedGroup;
20363             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20364                     "Setting sched group of " + app.processName
20365                     + " to " + app.curSchedGroup);
20366             if (app.waitingToKill != null && app.curReceiver == null
20367                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20368                 app.kill(app.waitingToKill, true);
20369                 success = false;
20370             } else {
20371                 int processGroup;
20372                 switch (app.curSchedGroup) {
20373                     case ProcessList.SCHED_GROUP_BACKGROUND:
20374                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20375                         break;
20376                     case ProcessList.SCHED_GROUP_TOP_APP:
20377                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20378                         processGroup = Process.THREAD_GROUP_TOP_APP;
20379                         break;
20380                     default:
20381                         processGroup = Process.THREAD_GROUP_DEFAULT;
20382                         break;
20383                 }
20384                 long oldId = Binder.clearCallingIdentity();
20385                 try {
20386                     Process.setProcessGroup(app.pid, processGroup);
20387                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20388                         // do nothing if we already switched to RT
20389                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20390                             // Switch VR thread for app to SCHED_FIFO
20391                             if (mInVrMode && app.vrThreadTid != 0) {
20392                                 try {
20393                                     Process.setThreadScheduler(app.vrThreadTid,
20394                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20395                                 } catch (IllegalArgumentException e) {
20396                                     // thread died, ignore
20397                                 }
20398                             }
20399                             if (mUseFifoUiScheduling) {
20400                                 // Switch UI pipeline for app to SCHED_FIFO
20401                                 app.savedPriority = Process.getThreadPriority(app.pid);
20402                                 try {
20403                                     Process.setThreadScheduler(app.pid,
20404                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20405                                 } catch (IllegalArgumentException e) {
20406                                     // thread died, ignore
20407                                 }
20408                                 if (app.renderThreadTid != 0) {
20409                                     try {
20410                                         Process.setThreadScheduler(app.renderThreadTid,
20411                                             Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20412                                     } catch (IllegalArgumentException e) {
20413                                         // thread died, ignore
20414                                     }
20415                                     if (DEBUG_OOM_ADJ) {
20416                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
20417                                             app.renderThreadTid + ") to FIFO");
20418                                     }
20419                                 } else {
20420                                     if (DEBUG_OOM_ADJ) {
20421                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
20422                                     }
20423                                 }
20424                             } else {
20425                                 // Boost priority for top app UI and render threads
20426                                 Process.setThreadPriority(app.pid, -10);
20427                                 if (app.renderThreadTid != 0) {
20428                                     try {
20429                                         Process.setThreadPriority(app.renderThreadTid, -10);
20430                                     } catch (IllegalArgumentException e) {
20431                                         // thread died, ignore
20432                                     }
20433                                 }
20434                             }
20435                         }
20436                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20437                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20438                         // Reset VR thread to SCHED_OTHER
20439                         // Safe to do even if we're not in VR mode
20440                         if (app.vrThreadTid != 0) {
20441                             Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20442                         }
20443                         if (mUseFifoUiScheduling) {
20444                             // Reset UI pipeline to SCHED_OTHER
20445                             Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20446                             Process.setThreadPriority(app.pid, app.savedPriority);
20447                             if (app.renderThreadTid != 0) {
20448                                 Process.setThreadScheduler(app.renderThreadTid,
20449                                     Process.SCHED_OTHER, 0);
20450                                 Process.setThreadPriority(app.renderThreadTid, -4);
20451                             }
20452                         } else {
20453                             // Reset priority for top app UI and render threads
20454                             Process.setThreadPriority(app.pid, 0);
20455                             if (app.renderThreadTid != 0) {
20456                                 Process.setThreadPriority(app.renderThreadTid, 0);
20457                             }
20458                         }
20459                     }
20460                 } catch (Exception e) {
20461                     Slog.w(TAG, "Failed setting process group of " + app.pid
20462                             + " to " + app.curSchedGroup);
20463                     e.printStackTrace();
20464                 } finally {
20465                     Binder.restoreCallingIdentity(oldId);
20466                 }
20467             }
20468         }
20469         if (app.repForegroundActivities != app.foregroundActivities) {
20470             app.repForegroundActivities = app.foregroundActivities;
20471             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20472         }
20473         if (app.repProcState != app.curProcState) {
20474             app.repProcState = app.curProcState;
20475             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20476             if (app.thread != null) {
20477                 try {
20478                     if (false) {
20479                         //RuntimeException h = new RuntimeException("here");
20480                         Slog.i(TAG, "Sending new process state " + app.repProcState
20481                                 + " to " + app /*, h*/);
20482                     }
20483                     app.thread.setProcessState(app.repProcState);
20484                 } catch (RemoteException e) {
20485                 }
20486             }
20487         }
20488         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20489                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20490             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20491                 // Experimental code to more aggressively collect pss while
20492                 // running test...  the problem is that this tends to collect
20493                 // the data right when a process is transitioning between process
20494                 // states, which well tend to give noisy data.
20495                 long start = SystemClock.uptimeMillis();
20496                 long pss = Debug.getPss(app.pid, mTmpLong, null);
20497                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20498                 mPendingPssProcesses.remove(app);
20499                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20500                         + " to " + app.curProcState + ": "
20501                         + (SystemClock.uptimeMillis()-start) + "ms");
20502             }
20503             app.lastStateTime = now;
20504             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20505                     mTestPssMode, isSleepingLocked(), now);
20506             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20507                     + ProcessList.makeProcStateString(app.setProcState) + " to "
20508                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20509                     + (app.nextPssTime-now) + ": " + app);
20510         } else {
20511             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20512                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20513                     mTestPssMode)))) {
20514                 requestPssLocked(app, app.setProcState);
20515                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20516                         mTestPssMode, isSleepingLocked(), now);
20517             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20518                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20519         }
20520         if (app.setProcState != app.curProcState) {
20521             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20522                     "Proc state change of " + app.processName
20523                             + " to " + app.curProcState);
20524             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20525             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20526             if (setImportant && !curImportant) {
20527                 // This app is no longer something we consider important enough to allow to
20528                 // use arbitrary amounts of battery power.  Note
20529                 // its current wake lock time to later know to kill it if
20530                 // it is not behaving well.
20531                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20532                 synchronized (stats) {
20533                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20534                             app.pid, nowElapsed);
20535                 }
20536                 app.lastCpuTime = app.curCpuTime;
20537 
20538             }
20539             // Inform UsageStats of important process state change
20540             // Must be called before updating setProcState
20541             maybeUpdateUsageStatsLocked(app, nowElapsed);
20542 
20543             app.setProcState = app.curProcState;
20544             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20545                 app.notCachedSinceIdle = false;
20546             }
20547             if (!doingAll) {
20548                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20549             } else {
20550                 app.procStateChanged = true;
20551             }
20552         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20553                 > USAGE_STATS_INTERACTION_INTERVAL) {
20554             // For apps that sit around for a long time in the interactive state, we need
20555             // to report this at least once a day so they don't go idle.
20556             maybeUpdateUsageStatsLocked(app, nowElapsed);
20557         }
20558 
20559         if (changes != 0) {
20560             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20561                     "Changes in " + app + ": " + changes);
20562             int i = mPendingProcessChanges.size()-1;
20563             ProcessChangeItem item = null;
20564             while (i >= 0) {
20565                 item = mPendingProcessChanges.get(i);
20566                 if (item.pid == app.pid) {
20567                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20568                             "Re-using existing item: " + item);
20569                     break;
20570                 }
20571                 i--;
20572             }
20573             if (i < 0) {
20574                 // No existing item in pending changes; need a new one.
20575                 final int NA = mAvailProcessChanges.size();
20576                 if (NA > 0) {
20577                     item = mAvailProcessChanges.remove(NA-1);
20578                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20579                             "Retrieving available item: " + item);
20580                 } else {
20581                     item = new ProcessChangeItem();
20582                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20583                             "Allocating new item: " + item);
20584                 }
20585                 item.changes = 0;
20586                 item.pid = app.pid;
20587                 item.uid = app.info.uid;
20588                 if (mPendingProcessChanges.size() == 0) {
20589                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20590                             "*** Enqueueing dispatch processes changed!");
20591                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20592                 }
20593                 mPendingProcessChanges.add(item);
20594             }
20595             item.changes |= changes;
20596             item.processState = app.repProcState;
20597             item.foregroundActivities = app.repForegroundActivities;
20598             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20599                     "Item " + Integer.toHexString(System.identityHashCode(item))
20600                     + " " + app.toShortString() + ": changes=" + item.changes
20601                     + " procState=" + item.processState
20602                     + " foreground=" + item.foregroundActivities
20603                     + " type=" + app.adjType + " source=" + app.adjSource
20604                     + " target=" + app.adjTarget);
20605         }
20606 
20607         return success;
20608     }
20609 
enqueueUidChangeLocked(UidRecord uidRec, int uid, int change)20610     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20611         final UidRecord.ChangeItem pendingChange;
20612         if (uidRec == null || uidRec.pendingChange == null) {
20613             if (mPendingUidChanges.size() == 0) {
20614                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20615                         "*** Enqueueing dispatch uid changed!");
20616                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20617             }
20618             final int NA = mAvailUidChanges.size();
20619             if (NA > 0) {
20620                 pendingChange = mAvailUidChanges.remove(NA-1);
20621                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20622                         "Retrieving available item: " + pendingChange);
20623             } else {
20624                 pendingChange = new UidRecord.ChangeItem();
20625                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20626                         "Allocating new item: " + pendingChange);
20627             }
20628             if (uidRec != null) {
20629                 uidRec.pendingChange = pendingChange;
20630                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20631                     // If this uid is going away, and we haven't yet reported it is gone,
20632                     // then do so now.
20633                     change = UidRecord.CHANGE_GONE_IDLE;
20634                 }
20635             } else if (uid < 0) {
20636                 throw new IllegalArgumentException("No UidRecord or uid");
20637             }
20638             pendingChange.uidRecord = uidRec;
20639             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20640             mPendingUidChanges.add(pendingChange);
20641         } else {
20642             pendingChange = uidRec.pendingChange;
20643             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20644                 change = UidRecord.CHANGE_GONE_IDLE;
20645             }
20646         }
20647         pendingChange.change = change;
20648         pendingChange.processState = uidRec != null
20649                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20650     }
20651 
maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName, String authority)20652     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20653             String authority) {
20654         if (app == null) return;
20655         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20656             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20657             if (userState == null) return;
20658             final long now = SystemClock.elapsedRealtime();
20659             Long lastReported = userState.mProviderLastReportedFg.get(authority);
20660             if (lastReported == null || lastReported < now - 60 * 1000L) {
20661                 mUsageStatsService.reportContentProviderUsage(
20662                         authority, providerPkgName, app.userId);
20663                 userState.mProviderLastReportedFg.put(authority, now);
20664             }
20665         }
20666     }
20667 
maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed)20668     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20669         if (DEBUG_USAGE_STATS) {
20670             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20671                     + "] state changes: old = " + app.setProcState + ", new = "
20672                     + app.curProcState);
20673         }
20674         if (mUsageStatsService == null) {
20675             return;
20676         }
20677         boolean isInteraction;
20678         // To avoid some abuse patterns, we are going to be careful about what we consider
20679         // to be an app interaction.  Being the top activity doesn't count while the display
20680         // is sleeping, nor do short foreground services.
20681         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20682             isInteraction = true;
20683             app.fgInteractionTime = 0;
20684         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20685             if (app.fgInteractionTime == 0) {
20686                 app.fgInteractionTime = nowElapsed;
20687                 isInteraction = false;
20688             } else {
20689                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20690             }
20691         } else {
20692             isInteraction = app.curProcState
20693                     <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20694             app.fgInteractionTime = 0;
20695         }
20696         if (isInteraction && (!app.reportedInteraction
20697                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20698             app.interactionEventTime = nowElapsed;
20699             String[] packages = app.getPackageList();
20700             if (packages != null) {
20701                 for (int i = 0; i < packages.length; i++) {
20702                     mUsageStatsService.reportEvent(packages[i], app.userId,
20703                             UsageEvents.Event.SYSTEM_INTERACTION);
20704                 }
20705             }
20706         }
20707         app.reportedInteraction = isInteraction;
20708         if (!isInteraction) {
20709             app.interactionEventTime = 0;
20710         }
20711     }
20712 
setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now)20713     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20714         if (proc.thread != null) {
20715             if (proc.baseProcessTracker != null) {
20716                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20717             }
20718         }
20719     }
20720 
updateOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP, boolean doingAll, long now)20721     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20722             ProcessRecord TOP_APP, boolean doingAll, long now) {
20723         if (app.thread == null) {
20724             return false;
20725         }
20726 
20727         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20728 
20729         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20730     }
20731 
updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground, boolean oomAdj)20732     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20733             boolean oomAdj) {
20734         if (isForeground != proc.foregroundServices) {
20735             proc.foregroundServices = isForeground;
20736             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20737                     proc.info.uid);
20738             if (isForeground) {
20739                 if (curProcs == null) {
20740                     curProcs = new ArrayList<ProcessRecord>();
20741                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20742                 }
20743                 if (!curProcs.contains(proc)) {
20744                     curProcs.add(proc);
20745                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20746                             proc.info.packageName, proc.info.uid);
20747                 }
20748             } else {
20749                 if (curProcs != null) {
20750                     if (curProcs.remove(proc)) {
20751                         mBatteryStatsService.noteEvent(
20752                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20753                                 proc.info.packageName, proc.info.uid);
20754                         if (curProcs.size() <= 0) {
20755                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20756                         }
20757                     }
20758                 }
20759             }
20760             if (oomAdj) {
20761                 updateOomAdjLocked();
20762             }
20763         }
20764     }
20765 
resumedAppLocked()20766     private final ActivityRecord resumedAppLocked() {
20767         ActivityRecord act = mStackSupervisor.resumedAppLocked();
20768         String pkg;
20769         int uid;
20770         if (act != null) {
20771             pkg = act.packageName;
20772             uid = act.info.applicationInfo.uid;
20773         } else {
20774             pkg = null;
20775             uid = -1;
20776         }
20777         // Has the UID or resumed package name changed?
20778         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20779                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20780             if (mCurResumedPackage != null) {
20781                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20782                         mCurResumedPackage, mCurResumedUid);
20783             }
20784             mCurResumedPackage = pkg;
20785             mCurResumedUid = uid;
20786             if (mCurResumedPackage != null) {
20787                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20788                         mCurResumedPackage, mCurResumedUid);
20789             }
20790         }
20791         return act;
20792     }
20793 
updateOomAdjLocked(ProcessRecord app)20794     final boolean updateOomAdjLocked(ProcessRecord app) {
20795         final ActivityRecord TOP_ACT = resumedAppLocked();
20796         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20797         final boolean wasCached = app.cached;
20798 
20799         mAdjSeq++;
20800 
20801         // This is the desired cached adjusment we want to tell it to use.
20802         // If our app is currently cached, we know it, and that is it.  Otherwise,
20803         // we don't know it yet, and it needs to now be cached we will then
20804         // need to do a complete oom adj.
20805         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20806                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20807         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20808                 SystemClock.uptimeMillis());
20809         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20810             // Changed to/from cached state, so apps after it in the LRU
20811             // list may also be changed.
20812             updateOomAdjLocked();
20813         }
20814         return success;
20815     }
20816 
updateOomAdjLocked()20817     final void updateOomAdjLocked() {
20818         final ActivityRecord TOP_ACT = resumedAppLocked();
20819         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20820         final long now = SystemClock.uptimeMillis();
20821         final long nowElapsed = SystemClock.elapsedRealtime();
20822         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20823         final int N = mLruProcesses.size();
20824 
20825         if (false) {
20826             RuntimeException e = new RuntimeException();
20827             e.fillInStackTrace();
20828             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20829         }
20830 
20831         // Reset state in all uid records.
20832         for (int i=mActiveUids.size()-1; i>=0; i--) {
20833             final UidRecord uidRec = mActiveUids.valueAt(i);
20834             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20835                     "Starting update of " + uidRec);
20836             uidRec.reset();
20837         }
20838 
20839         mStackSupervisor.rankTaskLayersIfNeeded();
20840 
20841         mAdjSeq++;
20842         mNewNumServiceProcs = 0;
20843         mNewNumAServiceProcs = 0;
20844 
20845         final int emptyProcessLimit;
20846         final int cachedProcessLimit;
20847         if (mProcessLimit <= 0) {
20848             emptyProcessLimit = cachedProcessLimit = 0;
20849         } else if (mProcessLimit == 1) {
20850             emptyProcessLimit = 1;
20851             cachedProcessLimit = 0;
20852         } else {
20853             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20854             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20855         }
20856 
20857         // Let's determine how many processes we have running vs.
20858         // how many slots we have for background processes; we may want
20859         // to put multiple processes in a slot of there are enough of
20860         // them.
20861         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20862                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20863         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20864         if (numEmptyProcs > cachedProcessLimit) {
20865             // If there are more empty processes than our limit on cached
20866             // processes, then use the cached process limit for the factor.
20867             // This ensures that the really old empty processes get pushed
20868             // down to the bottom, so if we are running low on memory we will
20869             // have a better chance at keeping around more cached processes
20870             // instead of a gazillion empty processes.
20871             numEmptyProcs = cachedProcessLimit;
20872         }
20873         int emptyFactor = numEmptyProcs/numSlots;
20874         if (emptyFactor < 1) emptyFactor = 1;
20875         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20876         if (cachedFactor < 1) cachedFactor = 1;
20877         int stepCached = 0;
20878         int stepEmpty = 0;
20879         int numCached = 0;
20880         int numEmpty = 0;
20881         int numTrimming = 0;
20882 
20883         mNumNonCachedProcs = 0;
20884         mNumCachedHiddenProcs = 0;
20885 
20886         // First update the OOM adjustment for each of the
20887         // application processes based on their current state.
20888         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20889         int nextCachedAdj = curCachedAdj+1;
20890         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20891         int nextEmptyAdj = curEmptyAdj+2;
20892         for (int i=N-1; i>=0; i--) {
20893             ProcessRecord app = mLruProcesses.get(i);
20894             if (!app.killedByAm && app.thread != null) {
20895                 app.procStateChanged = false;
20896                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20897 
20898                 // If we haven't yet assigned the final cached adj
20899                 // to the process, do that now.
20900                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20901                     switch (app.curProcState) {
20902                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20903                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20904                             // This process is a cached process holding activities...
20905                             // assign it the next cached value for that type, and then
20906                             // step that cached level.
20907                             app.curRawAdj = curCachedAdj;
20908                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20909                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20910                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20911                                     + ")");
20912                             if (curCachedAdj != nextCachedAdj) {
20913                                 stepCached++;
20914                                 if (stepCached >= cachedFactor) {
20915                                     stepCached = 0;
20916                                     curCachedAdj = nextCachedAdj;
20917                                     nextCachedAdj += 2;
20918                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20919                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
20920                                     }
20921                                 }
20922                             }
20923                             break;
20924                         default:
20925                             // For everything else, assign next empty cached process
20926                             // level and bump that up.  Note that this means that
20927                             // long-running services that have dropped down to the
20928                             // cached level will be treated as empty (since their process
20929                             // state is still as a service), which is what we want.
20930                             app.curRawAdj = curEmptyAdj;
20931                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
20932                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
20933                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
20934                                     + ")");
20935                             if (curEmptyAdj != nextEmptyAdj) {
20936                                 stepEmpty++;
20937                                 if (stepEmpty >= emptyFactor) {
20938                                     stepEmpty = 0;
20939                                     curEmptyAdj = nextEmptyAdj;
20940                                     nextEmptyAdj += 2;
20941                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
20942                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
20943                                     }
20944                                 }
20945                             }
20946                             break;
20947                     }
20948                 }
20949 
20950                 applyOomAdjLocked(app, true, now, nowElapsed);
20951 
20952                 // Count the number of process types.
20953                 switch (app.curProcState) {
20954                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20955                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20956                         mNumCachedHiddenProcs++;
20957                         numCached++;
20958                         if (numCached > cachedProcessLimit) {
20959                             app.kill("cached #" + numCached, true);
20960                         }
20961                         break;
20962                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
20963                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
20964                                 && app.lastActivityTime < oldTime) {
20965                             app.kill("empty for "
20966                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
20967                                     / 1000) + "s", true);
20968                         } else {
20969                             numEmpty++;
20970                             if (numEmpty > emptyProcessLimit) {
20971                                 app.kill("empty #" + numEmpty, true);
20972                             }
20973                         }
20974                         break;
20975                     default:
20976                         mNumNonCachedProcs++;
20977                         break;
20978                 }
20979 
20980                 if (app.isolated && app.services.size() <= 0) {
20981                     // If this is an isolated process, and there are no
20982                     // services running in it, then the process is no longer
20983                     // needed.  We agressively kill these because we can by
20984                     // definition not re-use the same process again, and it is
20985                     // good to avoid having whatever code was running in them
20986                     // left sitting around after no longer needed.
20987                     app.kill("isolated not needed", true);
20988                 } else {
20989                     // Keeping this process, update its uid.
20990                     final UidRecord uidRec = app.uidRecord;
20991                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
20992                         uidRec.curProcState = app.curProcState;
20993                     }
20994                 }
20995 
20996                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
20997                         && !app.killedByAm) {
20998                     numTrimming++;
20999                 }
21000             }
21001         }
21002 
21003         mNumServiceProcs = mNewNumServiceProcs;
21004 
21005         // Now determine the memory trimming level of background processes.
21006         // Unfortunately we need to start at the back of the list to do this
21007         // properly.  We only do this if the number of background apps we
21008         // are managing to keep around is less than half the maximum we desire;
21009         // if we are keeping a good number around, we'll let them use whatever
21010         // memory they want.
21011         final int numCachedAndEmpty = numCached + numEmpty;
21012         int memFactor;
21013         if (numCached <= ProcessList.TRIM_CACHED_APPS
21014                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21015             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21016                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21017             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21018                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21019             } else {
21020                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21021             }
21022         } else {
21023             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21024         }
21025         // We always allow the memory level to go up (better).  We only allow it to go
21026         // down if we are in a state where that is allowed, *and* the total number of processes
21027         // has gone down since last time.
21028         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21029                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21030                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21031         if (memFactor > mLastMemoryLevel) {
21032             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21033                 memFactor = mLastMemoryLevel;
21034                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21035             }
21036         }
21037         if (memFactor != mLastMemoryLevel) {
21038             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21039         }
21040         mLastMemoryLevel = memFactor;
21041         mLastNumProcesses = mLruProcesses.size();
21042         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21043         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21044         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21045             if (mLowRamStartTime == 0) {
21046                 mLowRamStartTime = now;
21047             }
21048             int step = 0;
21049             int fgTrimLevel;
21050             switch (memFactor) {
21051                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21052                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21053                     break;
21054                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21055                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21056                     break;
21057                 default:
21058                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21059                     break;
21060             }
21061             int factor = numTrimming/3;
21062             int minFactor = 2;
21063             if (mHomeProcess != null) minFactor++;
21064             if (mPreviousProcess != null) minFactor++;
21065             if (factor < minFactor) factor = minFactor;
21066             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21067             for (int i=N-1; i>=0; i--) {
21068                 ProcessRecord app = mLruProcesses.get(i);
21069                 if (allChanged || app.procStateChanged) {
21070                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21071                     app.procStateChanged = false;
21072                 }
21073                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21074                         && !app.killedByAm) {
21075                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
21076                         try {
21077                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21078                                     "Trimming memory of " + app.processName + " to " + curLevel);
21079                             app.thread.scheduleTrimMemory(curLevel);
21080                         } catch (RemoteException e) {
21081                         }
21082                         if (false) {
21083                             // For now we won't do this; our memory trimming seems
21084                             // to be good enough at this point that destroying
21085                             // activities causes more harm than good.
21086                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21087                                     && app != mHomeProcess && app != mPreviousProcess) {
21088                                 // Need to do this on its own message because the stack may not
21089                                 // be in a consistent state at this point.
21090                                 // For these apps we will also finish their activities
21091                                 // to help them free memory.
21092                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21093                             }
21094                         }
21095                     }
21096                     app.trimMemoryLevel = curLevel;
21097                     step++;
21098                     if (step >= factor) {
21099                         step = 0;
21100                         switch (curLevel) {
21101                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21102                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21103                                 break;
21104                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21105                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21106                                 break;
21107                         }
21108                     }
21109                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21110                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21111                             && app.thread != null) {
21112                         try {
21113                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21114                                     "Trimming memory of heavy-weight " + app.processName
21115                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21116                             app.thread.scheduleTrimMemory(
21117                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21118                         } catch (RemoteException e) {
21119                         }
21120                     }
21121                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21122                 } else {
21123                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21124                             || app.systemNoUi) && app.pendingUiClean) {
21125                         // If this application is now in the background and it
21126                         // had done UI, then give it the special trim level to
21127                         // have it free UI resources.
21128                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21129                         if (app.trimMemoryLevel < level && app.thread != null) {
21130                             try {
21131                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21132                                         "Trimming memory of bg-ui " + app.processName
21133                                         + " to " + level);
21134                                 app.thread.scheduleTrimMemory(level);
21135                             } catch (RemoteException e) {
21136                             }
21137                         }
21138                         app.pendingUiClean = false;
21139                     }
21140                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21141                         try {
21142                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21143                                     "Trimming memory of fg " + app.processName
21144                                     + " to " + fgTrimLevel);
21145                             app.thread.scheduleTrimMemory(fgTrimLevel);
21146                         } catch (RemoteException e) {
21147                         }
21148                     }
21149                     app.trimMemoryLevel = fgTrimLevel;
21150                 }
21151             }
21152         } else {
21153             if (mLowRamStartTime != 0) {
21154                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21155                 mLowRamStartTime = 0;
21156             }
21157             for (int i=N-1; i>=0; i--) {
21158                 ProcessRecord app = mLruProcesses.get(i);
21159                 if (allChanged || app.procStateChanged) {
21160                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21161                     app.procStateChanged = false;
21162                 }
21163                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21164                         || app.systemNoUi) && app.pendingUiClean) {
21165                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21166                             && app.thread != null) {
21167                         try {
21168                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21169                                     "Trimming memory of ui hidden " + app.processName
21170                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21171                             app.thread.scheduleTrimMemory(
21172                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21173                         } catch (RemoteException e) {
21174                         }
21175                     }
21176                     app.pendingUiClean = false;
21177                 }
21178                 app.trimMemoryLevel = 0;
21179             }
21180         }
21181 
21182         if (mAlwaysFinishActivities) {
21183             // Need to do this on its own message because the stack may not
21184             // be in a consistent state at this point.
21185             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21186         }
21187 
21188         if (allChanged) {
21189             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21190         }
21191 
21192         // Update from any uid changes.
21193         for (int i=mActiveUids.size()-1; i>=0; i--) {
21194             final UidRecord uidRec = mActiveUids.valueAt(i);
21195             int uidChange = UidRecord.CHANGE_PROCSTATE;
21196             if (uidRec.setProcState != uidRec.curProcState) {
21197                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21198                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21199                         + " to " + uidRec.curProcState);
21200                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21201                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21202                         uidRec.lastBackgroundTime = nowElapsed;
21203                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21204                             // Note: the background settle time is in elapsed realtime, while
21205                             // the handler time base is uptime.  All this means is that we may
21206                             // stop background uids later than we had intended, but that only
21207                             // happens because the device was sleeping so we are okay anyway.
21208                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21209                         }
21210                     }
21211                 } else {
21212                     if (uidRec.idle) {
21213                         uidChange = UidRecord.CHANGE_ACTIVE;
21214                         uidRec.idle = false;
21215                     }
21216                     uidRec.lastBackgroundTime = 0;
21217                 }
21218                 uidRec.setProcState = uidRec.curProcState;
21219                 enqueueUidChangeLocked(uidRec, -1, uidChange);
21220                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21221             }
21222         }
21223 
21224         if (mProcessStats.shouldWriteNowLocked(now)) {
21225             mHandler.post(new Runnable() {
21226                 @Override public void run() {
21227                     synchronized (ActivityManagerService.this) {
21228                         mProcessStats.writeStateAsyncLocked();
21229                     }
21230                 }
21231             });
21232         }
21233 
21234         if (DEBUG_OOM_ADJ) {
21235             final long duration = SystemClock.uptimeMillis() - now;
21236             if (false) {
21237                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21238                         new RuntimeException("here").fillInStackTrace());
21239             } else {
21240                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21241             }
21242         }
21243     }
21244 
idleUids()21245     final void idleUids() {
21246         synchronized (this) {
21247             final long nowElapsed = SystemClock.elapsedRealtime();
21248             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21249             long nextTime = 0;
21250             for (int i=mActiveUids.size()-1; i>=0; i--) {
21251                 final UidRecord uidRec = mActiveUids.valueAt(i);
21252                 final long bgTime = uidRec.lastBackgroundTime;
21253                 if (bgTime > 0 && !uidRec.idle) {
21254                     if (bgTime <= maxBgTime) {
21255                         uidRec.idle = true;
21256                         doStopUidLocked(uidRec.uid, uidRec);
21257                     } else {
21258                         if (nextTime == 0 || nextTime > bgTime) {
21259                             nextTime = bgTime;
21260                         }
21261                     }
21262                 }
21263             }
21264             if (nextTime > 0) {
21265                 mHandler.removeMessages(IDLE_UIDS_MSG);
21266                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21267                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21268             }
21269         }
21270     }
21271 
runInBackgroundDisabled(int uid)21272     final void runInBackgroundDisabled(int uid) {
21273         synchronized (this) {
21274             UidRecord uidRec = mActiveUids.get(uid);
21275             if (uidRec != null) {
21276                 // This uid is actually running...  should it be considered background now?
21277                 if (uidRec.idle) {
21278                     doStopUidLocked(uidRec.uid, uidRec);
21279                 }
21280             } else {
21281                 // This uid isn't actually running...  still send a report about it being "stopped".
21282                 doStopUidLocked(uid, null);
21283             }
21284         }
21285     }
21286 
doStopUidLocked(int uid, final UidRecord uidRec)21287     final void doStopUidLocked(int uid, final UidRecord uidRec) {
21288         mServices.stopInBackgroundLocked(uid);
21289         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21290     }
21291 
trimApplications()21292     final void trimApplications() {
21293         synchronized (this) {
21294             int i;
21295 
21296             // First remove any unused application processes whose package
21297             // has been removed.
21298             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21299                 final ProcessRecord app = mRemovedProcesses.get(i);
21300                 if (app.activities.size() == 0
21301                         && app.curReceiver == null && app.services.size() == 0) {
21302                     Slog.i(
21303                         TAG, "Exiting empty application process "
21304                         + app.toShortString() + " ("
21305                         + (app.thread != null ? app.thread.asBinder() : null)
21306                         + ")\n");
21307                     if (app.pid > 0 && app.pid != MY_PID) {
21308                         app.kill("empty", false);
21309                     } else {
21310                         try {
21311                             app.thread.scheduleExit();
21312                         } catch (Exception e) {
21313                             // Ignore exceptions.
21314                         }
21315                     }
21316                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21317                     mRemovedProcesses.remove(i);
21318 
21319                     if (app.persistent) {
21320                         addAppLocked(app.info, false, null /* ABI override */);
21321                     }
21322                 }
21323             }
21324 
21325             // Now update the oom adj for all processes.
21326             updateOomAdjLocked();
21327         }
21328     }
21329 
21330     /** This method sends the specified signal to each of the persistent apps */
signalPersistentProcesses(int sig)21331     public void signalPersistentProcesses(int sig) throws RemoteException {
21332         if (sig != Process.SIGNAL_USR1) {
21333             throw new SecurityException("Only SIGNAL_USR1 is allowed");
21334         }
21335 
21336         synchronized (this) {
21337             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21338                     != PackageManager.PERMISSION_GRANTED) {
21339                 throw new SecurityException("Requires permission "
21340                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21341             }
21342 
21343             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21344                 ProcessRecord r = mLruProcesses.get(i);
21345                 if (r.thread != null && r.persistent) {
21346                     Process.sendSignal(r.pid, sig);
21347                 }
21348             }
21349         }
21350     }
21351 
stopProfilerLocked(ProcessRecord proc, int profileType)21352     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21353         if (proc == null || proc == mProfileProc) {
21354             proc = mProfileProc;
21355             profileType = mProfileType;
21356             clearProfilerLocked();
21357         }
21358         if (proc == null) {
21359             return;
21360         }
21361         try {
21362             proc.thread.profilerControl(false, null, profileType);
21363         } catch (RemoteException e) {
21364             throw new IllegalStateException("Process disappeared");
21365         }
21366     }
21367 
clearProfilerLocked()21368     private void clearProfilerLocked() {
21369         if (mProfileFd != null) {
21370             try {
21371                 mProfileFd.close();
21372             } catch (IOException e) {
21373             }
21374         }
21375         mProfileApp = null;
21376         mProfileProc = null;
21377         mProfileFile = null;
21378         mProfileType = 0;
21379         mAutoStopProfiler = false;
21380         mSamplingInterval = 0;
21381     }
21382 
profileControl(String process, int userId, boolean start, ProfilerInfo profilerInfo, int profileType)21383     public boolean profileControl(String process, int userId, boolean start,
21384             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21385 
21386         try {
21387             synchronized (this) {
21388                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21389                 // its own permission.
21390                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21391                         != PackageManager.PERMISSION_GRANTED) {
21392                     throw new SecurityException("Requires permission "
21393                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21394                 }
21395 
21396                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21397                     throw new IllegalArgumentException("null profile info or fd");
21398                 }
21399 
21400                 ProcessRecord proc = null;
21401                 if (process != null) {
21402                     proc = findProcessLocked(process, userId, "profileControl");
21403                 }
21404 
21405                 if (start && (proc == null || proc.thread == null)) {
21406                     throw new IllegalArgumentException("Unknown process: " + process);
21407                 }
21408 
21409                 if (start) {
21410                     stopProfilerLocked(null, 0);
21411                     setProfileApp(proc.info, proc.processName, profilerInfo);
21412                     mProfileProc = proc;
21413                     mProfileType = profileType;
21414                     ParcelFileDescriptor fd = profilerInfo.profileFd;
21415                     try {
21416                         fd = fd.dup();
21417                     } catch (IOException e) {
21418                         fd = null;
21419                     }
21420                     profilerInfo.profileFd = fd;
21421                     proc.thread.profilerControl(start, profilerInfo, profileType);
21422                     fd = null;
21423                     mProfileFd = null;
21424                 } else {
21425                     stopProfilerLocked(proc, profileType);
21426                     if (profilerInfo != null && profilerInfo.profileFd != null) {
21427                         try {
21428                             profilerInfo.profileFd.close();
21429                         } catch (IOException e) {
21430                         }
21431                     }
21432                 }
21433 
21434                 return true;
21435             }
21436         } catch (RemoteException e) {
21437             throw new IllegalStateException("Process disappeared");
21438         } finally {
21439             if (profilerInfo != null && profilerInfo.profileFd != null) {
21440                 try {
21441                     profilerInfo.profileFd.close();
21442                 } catch (IOException e) {
21443                 }
21444             }
21445         }
21446     }
21447 
findProcessLocked(String process, int userId, String callName)21448     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21449         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21450                 userId, true, ALLOW_FULL_ONLY, callName, null);
21451         ProcessRecord proc = null;
21452         try {
21453             int pid = Integer.parseInt(process);
21454             synchronized (mPidsSelfLocked) {
21455                 proc = mPidsSelfLocked.get(pid);
21456             }
21457         } catch (NumberFormatException e) {
21458         }
21459 
21460         if (proc == null) {
21461             ArrayMap<String, SparseArray<ProcessRecord>> all
21462                     = mProcessNames.getMap();
21463             SparseArray<ProcessRecord> procs = all.get(process);
21464             if (procs != null && procs.size() > 0) {
21465                 proc = procs.valueAt(0);
21466                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21467                     for (int i=1; i<procs.size(); i++) {
21468                         ProcessRecord thisProc = procs.valueAt(i);
21469                         if (thisProc.userId == userId) {
21470                             proc = thisProc;
21471                             break;
21472                         }
21473                     }
21474                 }
21475             }
21476         }
21477 
21478         return proc;
21479     }
21480 
dumpHeap(String process, int userId, boolean managed, String path, ParcelFileDescriptor fd)21481     public boolean dumpHeap(String process, int userId, boolean managed,
21482             String path, ParcelFileDescriptor fd) throws RemoteException {
21483 
21484         try {
21485             synchronized (this) {
21486                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21487                 // its own permission (same as profileControl).
21488                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21489                         != PackageManager.PERMISSION_GRANTED) {
21490                     throw new SecurityException("Requires permission "
21491                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21492                 }
21493 
21494                 if (fd == null) {
21495                     throw new IllegalArgumentException("null fd");
21496                 }
21497 
21498                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21499                 if (proc == null || proc.thread == null) {
21500                     throw new IllegalArgumentException("Unknown process: " + process);
21501                 }
21502 
21503                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21504                 if (!isDebuggable) {
21505                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21506                         throw new SecurityException("Process not debuggable: " + proc);
21507                     }
21508                 }
21509 
21510                 proc.thread.dumpHeap(managed, path, fd);
21511                 fd = null;
21512                 return true;
21513             }
21514         } catch (RemoteException e) {
21515             throw new IllegalStateException("Process disappeared");
21516         } finally {
21517             if (fd != null) {
21518                 try {
21519                     fd.close();
21520                 } catch (IOException e) {
21521                 }
21522             }
21523         }
21524     }
21525 
21526     @Override
setDumpHeapDebugLimit(String processName, int uid, long maxMemSize, String reportPackage)21527     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21528             String reportPackage) {
21529         if (processName != null) {
21530             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21531                     "setDumpHeapDebugLimit()");
21532         } else {
21533             synchronized (mPidsSelfLocked) {
21534                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21535                 if (proc == null) {
21536                     throw new SecurityException("No process found for calling pid "
21537                             + Binder.getCallingPid());
21538                 }
21539                 if (!Build.IS_DEBUGGABLE
21540                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21541                     throw new SecurityException("Not running a debuggable build");
21542                 }
21543                 processName = proc.processName;
21544                 uid = proc.uid;
21545                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21546                     throw new SecurityException("Package " + reportPackage + " is not running in "
21547                             + proc);
21548                 }
21549             }
21550         }
21551         synchronized (this) {
21552             if (maxMemSize > 0) {
21553                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21554             } else {
21555                 if (uid != 0) {
21556                     mMemWatchProcesses.remove(processName, uid);
21557                 } else {
21558                     mMemWatchProcesses.getMap().remove(processName);
21559                 }
21560             }
21561         }
21562     }
21563 
21564     @Override
dumpHeapFinished(String path)21565     public void dumpHeapFinished(String path) {
21566         synchronized (this) {
21567             if (Binder.getCallingPid() != mMemWatchDumpPid) {
21568                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21569                         + " does not match last pid " + mMemWatchDumpPid);
21570                 return;
21571             }
21572             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21573                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21574                         + " does not match last path " + mMemWatchDumpFile);
21575                 return;
21576             }
21577             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21578             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21579         }
21580     }
21581 
21582     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
monitor()21583     public void monitor() {
21584         synchronized (this) { }
21585     }
21586 
onCoreSettingsChange(Bundle settings)21587     void onCoreSettingsChange(Bundle settings) {
21588         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21589             ProcessRecord processRecord = mLruProcesses.get(i);
21590             try {
21591                 if (processRecord.thread != null) {
21592                     processRecord.thread.setCoreSettings(settings);
21593                 }
21594             } catch (RemoteException re) {
21595                 /* ignore */
21596             }
21597         }
21598     }
21599 
21600     // Multi-user methods
21601 
21602     /**
21603      * Start user, if its not already running, but don't bring it to foreground.
21604      */
21605     @Override
startUserInBackground(final int userId)21606     public boolean startUserInBackground(final int userId) {
21607         return mUserController.startUser(userId, /* foreground */ false);
21608     }
21609 
21610     @Override
unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener)21611     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21612         return mUserController.unlockUser(userId, token, secret, listener);
21613     }
21614 
21615     @Override
switchUser(final int targetUserId)21616     public boolean switchUser(final int targetUserId) {
21617         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21618         UserInfo currentUserInfo;
21619         UserInfo targetUserInfo;
21620         synchronized (this) {
21621             int currentUserId = mUserController.getCurrentUserIdLocked();
21622             currentUserInfo = mUserController.getUserInfo(currentUserId);
21623             targetUserInfo = mUserController.getUserInfo(targetUserId);
21624             if (targetUserInfo == null) {
21625                 Slog.w(TAG, "No user info for user #" + targetUserId);
21626                 return false;
21627             }
21628             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21629                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21630                         + " when device is in demo mode");
21631                 return false;
21632             }
21633             if (!targetUserInfo.supportsSwitchTo()) {
21634                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21635                 return false;
21636             }
21637             if (targetUserInfo.isManagedProfile()) {
21638                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21639                 return false;
21640             }
21641             mUserController.setTargetUserIdLocked(targetUserId);
21642         }
21643         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21644         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21645         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21646         return true;
21647     }
21648 
scheduleStartProfilesLocked()21649     void scheduleStartProfilesLocked() {
21650         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21651             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21652                     DateUtils.SECOND_IN_MILLIS);
21653         }
21654     }
21655 
21656     @Override
stopUser(final int userId, boolean force, final IStopUserCallback callback)21657     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21658         return mUserController.stopUser(userId, force, callback);
21659     }
21660 
21661     @Override
getCurrentUser()21662     public UserInfo getCurrentUser() {
21663         return mUserController.getCurrentUser();
21664     }
21665 
21666     @Override
isUserRunning(int userId, int flags)21667     public boolean isUserRunning(int userId, int flags) {
21668         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21669                 && checkCallingPermission(INTERACT_ACROSS_USERS)
21670                     != PackageManager.PERMISSION_GRANTED) {
21671             String msg = "Permission Denial: isUserRunning() from pid="
21672                     + Binder.getCallingPid()
21673                     + ", uid=" + Binder.getCallingUid()
21674                     + " requires " + INTERACT_ACROSS_USERS;
21675             Slog.w(TAG, msg);
21676             throw new SecurityException(msg);
21677         }
21678         synchronized (this) {
21679             return mUserController.isUserRunningLocked(userId, flags);
21680         }
21681     }
21682 
21683     @Override
getRunningUserIds()21684     public int[] getRunningUserIds() {
21685         if (checkCallingPermission(INTERACT_ACROSS_USERS)
21686                 != PackageManager.PERMISSION_GRANTED) {
21687             String msg = "Permission Denial: isUserRunning() from pid="
21688                     + Binder.getCallingPid()
21689                     + ", uid=" + Binder.getCallingUid()
21690                     + " requires " + INTERACT_ACROSS_USERS;
21691             Slog.w(TAG, msg);
21692             throw new SecurityException(msg);
21693         }
21694         synchronized (this) {
21695             return mUserController.getStartedUserArrayLocked();
21696         }
21697     }
21698 
21699     @Override
registerUserSwitchObserver(IUserSwitchObserver observer, String name)21700     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21701         mUserController.registerUserSwitchObserver(observer, name);
21702     }
21703 
21704     @Override
unregisterUserSwitchObserver(IUserSwitchObserver observer)21705     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21706         mUserController.unregisterUserSwitchObserver(observer);
21707     }
21708 
getAppInfoForUser(ApplicationInfo info, int userId)21709     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21710         if (info == null) return null;
21711         ApplicationInfo newInfo = new ApplicationInfo(info);
21712         newInfo.initForUser(userId);
21713         return newInfo;
21714     }
21715 
isUserStopped(int userId)21716     public boolean isUserStopped(int userId) {
21717         synchronized (this) {
21718             return mUserController.getStartedUserStateLocked(userId) == null;
21719         }
21720     }
21721 
getActivityInfoForUser(ActivityInfo aInfo, int userId)21722     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21723         if (aInfo == null
21724                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21725             return aInfo;
21726         }
21727 
21728         ActivityInfo info = new ActivityInfo(aInfo);
21729         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21730         return info;
21731     }
21732 
processSanityChecksLocked(ProcessRecord process)21733     private boolean processSanityChecksLocked(ProcessRecord process) {
21734         if (process == null || process.thread == null) {
21735             return false;
21736         }
21737 
21738         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21739         if (!isDebuggable) {
21740             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21741                 return false;
21742             }
21743         }
21744 
21745         return true;
21746     }
21747 
startBinderTracking()21748     public boolean startBinderTracking() throws RemoteException {
21749         synchronized (this) {
21750             mBinderTransactionTrackingEnabled = true;
21751             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21752             // permission (same as profileControl).
21753             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21754                     != PackageManager.PERMISSION_GRANTED) {
21755                 throw new SecurityException("Requires permission "
21756                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21757             }
21758 
21759             for (int i = 0; i < mLruProcesses.size(); i++) {
21760                 ProcessRecord process = mLruProcesses.get(i);
21761                 if (!processSanityChecksLocked(process)) {
21762                     continue;
21763                 }
21764                 try {
21765                     process.thread.startBinderTracking();
21766                 } catch (RemoteException e) {
21767                     Log.v(TAG, "Process disappared");
21768                 }
21769             }
21770             return true;
21771         }
21772     }
21773 
stopBinderTrackingAndDump(ParcelFileDescriptor fd)21774     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21775         try {
21776             synchronized (this) {
21777                 mBinderTransactionTrackingEnabled = false;
21778                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21779                 // permission (same as profileControl).
21780                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21781                         != PackageManager.PERMISSION_GRANTED) {
21782                     throw new SecurityException("Requires permission "
21783                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21784                 }
21785 
21786                 if (fd == null) {
21787                     throw new IllegalArgumentException("null fd");
21788                 }
21789 
21790                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21791                 pw.println("Binder transaction traces for all processes.\n");
21792                 for (ProcessRecord process : mLruProcesses) {
21793                     if (!processSanityChecksLocked(process)) {
21794                         continue;
21795                     }
21796 
21797                     pw.println("Traces for process: " + process.processName);
21798                     pw.flush();
21799                     try {
21800                         TransferPipe tp = new TransferPipe();
21801                         try {
21802                             process.thread.stopBinderTrackingAndDump(
21803                                     tp.getWriteFd().getFileDescriptor());
21804                             tp.go(fd.getFileDescriptor());
21805                         } finally {
21806                             tp.kill();
21807                         }
21808                     } catch (IOException e) {
21809                         pw.println("Failure while dumping IPC traces from " + process +
21810                                 ".  Exception: " + e);
21811                         pw.flush();
21812                     } catch (RemoteException e) {
21813                         pw.println("Got a RemoteException while dumping IPC traces from " +
21814                                 process + ".  Exception: " + e);
21815                         pw.flush();
21816                     }
21817                 }
21818                 fd = null;
21819                 return true;
21820             }
21821         } finally {
21822             if (fd != null) {
21823                 try {
21824                     fd.close();
21825                 } catch (IOException e) {
21826                 }
21827             }
21828         }
21829     }
21830 
21831     private final class LocalService extends ActivityManagerInternal {
21832         @Override
onWakefulnessChanged(int wakefulness)21833         public void onWakefulnessChanged(int wakefulness) {
21834             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21835         }
21836 
21837         @Override
startIsolatedProcess(String entryPoint, String[] entryPointArgs, String processName, String abiOverride, int uid, Runnable crashHandler)21838         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21839                 String processName, String abiOverride, int uid, Runnable crashHandler) {
21840             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21841                     processName, abiOverride, uid, crashHandler);
21842         }
21843 
21844         @Override
acquireSleepToken(String tag)21845         public SleepToken acquireSleepToken(String tag) {
21846             Preconditions.checkNotNull(tag);
21847 
21848             ComponentName requestedVrService = null;
21849             ComponentName callingVrActivity = null;
21850             int userId = -1;
21851             synchronized (ActivityManagerService.this) {
21852                 if (mFocusedActivity != null) {
21853                     requestedVrService = mFocusedActivity.requestedVrComponent;
21854                     callingVrActivity = mFocusedActivity.info.getComponentName();
21855                     userId = mFocusedActivity.userId;
21856                 }
21857             }
21858 
21859             if (requestedVrService != null) {
21860                 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21861             }
21862 
21863             synchronized (ActivityManagerService.this) {
21864                 SleepTokenImpl token = new SleepTokenImpl(tag);
21865                 mSleepTokens.add(token);
21866                 updateSleepIfNeededLocked();
21867                 return token;
21868             }
21869         }
21870 
21871         @Override
getHomeActivityForUser(int userId)21872         public ComponentName getHomeActivityForUser(int userId) {
21873             synchronized (ActivityManagerService.this) {
21874                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21875                 return homeActivity == null ? null : homeActivity.realActivity;
21876             }
21877         }
21878 
21879         @Override
onUserRemoved(int userId)21880         public void onUserRemoved(int userId) {
21881             synchronized (ActivityManagerService.this) {
21882                 ActivityManagerService.this.onUserStoppedLocked(userId);
21883             }
21884         }
21885 
21886         @Override
onLocalVoiceInteractionStarted(IBinder activity, IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor)21887         public void onLocalVoiceInteractionStarted(IBinder activity,
21888                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21889             synchronized (ActivityManagerService.this) {
21890                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21891                         voiceSession, voiceInteractor);
21892             }
21893         }
21894 
21895         @Override
notifyStartingWindowDrawn()21896         public void notifyStartingWindowDrawn() {
21897             synchronized (ActivityManagerService.this) {
21898                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
21899             }
21900         }
21901 
21902         @Override
notifyAppTransitionStarting(int reason)21903         public void notifyAppTransitionStarting(int reason) {
21904             synchronized (ActivityManagerService.this) {
21905                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
21906             }
21907         }
21908 
21909         @Override
notifyAppTransitionFinished()21910         public void notifyAppTransitionFinished() {
21911             synchronized (ActivityManagerService.this) {
21912                 mStackSupervisor.notifyAppTransitionDone();
21913             }
21914         }
21915 
21916         @Override
notifyAppTransitionCancelled()21917         public void notifyAppTransitionCancelled() {
21918             synchronized (ActivityManagerService.this) {
21919                 mStackSupervisor.notifyAppTransitionDone();
21920             }
21921         }
21922 
21923         @Override
getTopVisibleActivities()21924         public List<IBinder> getTopVisibleActivities() {
21925             synchronized (ActivityManagerService.this) {
21926                 return mStackSupervisor.getTopVisibleActivities();
21927             }
21928         }
21929 
21930         @Override
notifyDockedStackMinimizedChanged(boolean minimized)21931         public void notifyDockedStackMinimizedChanged(boolean minimized) {
21932             synchronized (ActivityManagerService.this) {
21933                 mStackSupervisor.setDockedStackMinimized(minimized);
21934             }
21935         }
21936 
21937         @Override
killForegroundAppsForUser(int userHandle)21938         public void killForegroundAppsForUser(int userHandle) {
21939             synchronized (ActivityManagerService.this) {
21940                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
21941                 final int NP = mProcessNames.getMap().size();
21942                 for (int ip = 0; ip < NP; ip++) {
21943                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
21944                     final int NA = apps.size();
21945                     for (int ia = 0; ia < NA; ia++) {
21946                         final ProcessRecord app = apps.valueAt(ia);
21947                         if (app.persistent) {
21948                             // We don't kill persistent processes.
21949                             continue;
21950                         }
21951                         if (app.removed) {
21952                             procs.add(app);
21953                         } else if (app.userId == userHandle && app.foregroundActivities) {
21954                             app.removed = true;
21955                             procs.add(app);
21956                         }
21957                     }
21958                 }
21959 
21960                 final int N = procs.size();
21961                 for (int i = 0; i < N; i++) {
21962                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
21963                 }
21964             }
21965         }
21966 
21967         @Override
setPendingIntentWhitelistDuration(IIntentSender target, long duration)21968         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
21969             if (!(target instanceof PendingIntentRecord)) {
21970                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
21971                 return;
21972             }
21973             ((PendingIntentRecord) target).setWhitelistDuration(duration);
21974         }
21975 
21976         @Override
updatePersistentConfigurationForUser(@onNull Configuration values, int userId)21977         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
21978                 int userId) {
21979             Preconditions.checkNotNull(values, "Configuration must not be null");
21980             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
21981             synchronized (ActivityManagerService.this) {
21982                 updateConfigurationLocked(values, null, false, true, userId,
21983                         false /* deferResume */);
21984             }
21985         }
21986 
21987         @Override
startActivitiesAsPackage(String packageName, int userId, Intent[] intents, Bundle bOptions)21988         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
21989                 Bundle bOptions) {
21990             Preconditions.checkNotNull(intents, "intents");
21991             final String[] resolvedTypes = new String[intents.length];
21992             for (int i = 0; i < intents.length; i++) {
21993                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
21994             }
21995 
21996             // UID of the package on user userId.
21997             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
21998             // packageUid may not be initialized.
21999             int packageUid = 0;
22000             try {
22001                 packageUid = AppGlobals.getPackageManager().getPackageUid(
22002                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22003             } catch (RemoteException e) {
22004                 // Shouldn't happen.
22005             }
22006 
22007             synchronized (ActivityManagerService.this) {
22008                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22009                         /*resultTo*/ null, bOptions, userId);
22010             }
22011         }
22012 
22013         @Override
getUidProcessState(int uid)22014         public int getUidProcessState(int uid) {
22015             return getUidState(uid);
22016         }
22017     }
22018 
22019     private final class SleepTokenImpl extends SleepToken {
22020         private final String mTag;
22021         private final long mAcquireTime;
22022 
SleepTokenImpl(String tag)22023         public SleepTokenImpl(String tag) {
22024             mTag = tag;
22025             mAcquireTime = SystemClock.uptimeMillis();
22026         }
22027 
22028         @Override
release()22029         public void release() {
22030             synchronized (ActivityManagerService.this) {
22031                 if (mSleepTokens.remove(this)) {
22032                     updateSleepIfNeededLocked();
22033                 }
22034             }
22035         }
22036 
22037         @Override
toString()22038         public String toString() {
22039             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22040         }
22041     }
22042 
22043     /**
22044      * An implementation of IAppTask, that allows an app to manage its own tasks via
22045      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22046      * only the process that calls getAppTasks() can call the AppTask methods.
22047      */
22048     class AppTaskImpl extends IAppTask.Stub {
22049         private int mTaskId;
22050         private int mCallingUid;
22051 
AppTaskImpl(int taskId, int callingUid)22052         public AppTaskImpl(int taskId, int callingUid) {
22053             mTaskId = taskId;
22054             mCallingUid = callingUid;
22055         }
22056 
checkCaller()22057         private void checkCaller() {
22058             if (mCallingUid != Binder.getCallingUid()) {
22059                 throw new SecurityException("Caller " + mCallingUid
22060                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22061             }
22062         }
22063 
22064         @Override
finishAndRemoveTask()22065         public void finishAndRemoveTask() {
22066             checkCaller();
22067 
22068             synchronized (ActivityManagerService.this) {
22069                 long origId = Binder.clearCallingIdentity();
22070                 try {
22071                     // We remove the task from recents to preserve backwards
22072                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22073                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22074                     }
22075                 } finally {
22076                     Binder.restoreCallingIdentity(origId);
22077                 }
22078             }
22079         }
22080 
22081         @Override
getTaskInfo()22082         public ActivityManager.RecentTaskInfo getTaskInfo() {
22083             checkCaller();
22084 
22085             synchronized (ActivityManagerService.this) {
22086                 long origId = Binder.clearCallingIdentity();
22087                 try {
22088                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22089                     if (tr == null) {
22090                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22091                     }
22092                     return createRecentTaskInfoFromTaskRecord(tr);
22093                 } finally {
22094                     Binder.restoreCallingIdentity(origId);
22095                 }
22096             }
22097         }
22098 
22099         @Override
moveToFront()22100         public void moveToFront() {
22101             checkCaller();
22102             // Will bring task to front if it already has a root activity.
22103             final long origId = Binder.clearCallingIdentity();
22104             try {
22105                 synchronized (this) {
22106                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22107                 }
22108             } finally {
22109                 Binder.restoreCallingIdentity(origId);
22110             }
22111         }
22112 
22113         @Override
startActivity(IBinder whoThread, String callingPackage, Intent intent, String resolvedType, Bundle bOptions)22114         public int startActivity(IBinder whoThread, String callingPackage,
22115                 Intent intent, String resolvedType, Bundle bOptions) {
22116             checkCaller();
22117 
22118             int callingUser = UserHandle.getCallingUserId();
22119             TaskRecord tr;
22120             IApplicationThread appThread;
22121             synchronized (ActivityManagerService.this) {
22122                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22123                 if (tr == null) {
22124                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22125                 }
22126                 appThread = ApplicationThreadNative.asInterface(whoThread);
22127                 if (appThread == null) {
22128                     throw new IllegalArgumentException("Bad app thread " + appThread);
22129                 }
22130             }
22131             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22132                     resolvedType, null, null, null, null, 0, 0, null, null,
22133                     null, bOptions, false, callingUser, null, tr);
22134         }
22135 
22136         @Override
setExcludeFromRecents(boolean exclude)22137         public void setExcludeFromRecents(boolean exclude) {
22138             checkCaller();
22139 
22140             synchronized (ActivityManagerService.this) {
22141                 long origId = Binder.clearCallingIdentity();
22142                 try {
22143                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22144                     if (tr == null) {
22145                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22146                     }
22147                     Intent intent = tr.getBaseIntent();
22148                     if (exclude) {
22149                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22150                     } else {
22151                         intent.setFlags(intent.getFlags()
22152                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22153                     }
22154                 } finally {
22155                     Binder.restoreCallingIdentity(origId);
22156                 }
22157             }
22158         }
22159     }
22160 
22161     /**
22162      * Kill processes for the user with id userId and that depend on the package named packageName
22163      */
22164     @Override
killPackageDependents(String packageName, int userId)22165     public void killPackageDependents(String packageName, int userId) {
22166         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22167         if (packageName == null) {
22168             throw new NullPointerException(
22169                     "Cannot kill the dependents of a package without its name.");
22170         }
22171 
22172         long callingId = Binder.clearCallingIdentity();
22173         IPackageManager pm = AppGlobals.getPackageManager();
22174         int pkgUid = -1;
22175         try {
22176             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22177         } catch (RemoteException e) {
22178         }
22179         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22180             throw new IllegalArgumentException(
22181                     "Cannot kill dependents of non-existing package " + packageName);
22182         }
22183         try {
22184             synchronized(this) {
22185                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22186                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22187                         "dep: " + packageName);
22188             }
22189         } finally {
22190             Binder.restoreCallingIdentity(callingId);
22191         }
22192     }
22193 }
22194