OSDN Git Service

[automerger] [RESTRICT AUTOMERGE]: Add cross user permission check - areNotifications...
[android-x86/frameworks-base.git] / services / core / java / com / android / server / am / ActivityManagerService.java
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.provider.Downloads;
194 import android.os.storage.IMountService;
195 import android.os.storage.MountServiceInternal;
196 import android.os.storage.StorageManager;
197 import android.provider.Settings;
198 import android.service.voice.IVoiceInteractionSession;
199 import android.service.voice.VoiceInteractionManagerInternal;
200 import android.service.voice.VoiceInteractionSession;
201 import android.telecom.TelecomManager;
202 import android.text.format.DateUtils;
203 import android.text.format.Time;
204 import android.text.style.SuggestionSpan;
205 import android.util.ArrayMap;
206 import android.util.ArraySet;
207 import android.util.AtomicFile;
208 import android.util.DebugUtils;
209 import android.util.DisplayMetrics;
210 import android.util.EventLog;
211 import android.util.Log;
212 import android.util.Pair;
213 import android.util.PrintWriterPrinter;
214 import android.util.Slog;
215 import android.util.SparseArray;
216 import android.util.TimeUtils;
217 import android.util.Xml;
218 import android.view.Display;
219 import android.view.Gravity;
220 import android.view.LayoutInflater;
221 import android.view.View;
222 import android.view.WindowManager;
223
224 import java.io.File;
225 import java.io.FileDescriptor;
226 import java.io.FileInputStream;
227 import java.io.FileNotFoundException;
228 import java.io.FileOutputStream;
229 import java.io.IOException;
230 import java.io.InputStreamReader;
231 import java.io.PrintWriter;
232 import java.io.StringWriter;
233 import java.lang.ref.WeakReference;
234 import java.nio.charset.StandardCharsets;
235 import java.util.ArrayList;
236 import java.util.Arrays;
237 import java.util.Collections;
238 import java.util.Comparator;
239 import java.util.HashMap;
240 import java.util.HashSet;
241 import java.util.Iterator;
242 import java.util.List;
243 import java.util.Locale;
244 import java.util.Map;
245 import java.util.Objects;
246 import java.util.Set;
247 import java.util.concurrent.atomic.AtomicBoolean;
248 import java.util.concurrent.atomic.AtomicLong;
249
250 import dalvik.system.VMRuntime;
251
252 import libcore.io.IoUtils;
253 import libcore.util.EmptyArray;
254
255 import static android.Manifest.permission.INTERACT_ACROSS_USERS;
256 import static android.Manifest.permission.INTERACT_ACROSS_USERS_FULL;
257 import static android.Manifest.permission.MANAGE_ACTIVITY_STACKS;
258 import static android.Manifest.permission.START_TASKS_FROM_RECENTS;
259 import static android.app.ActivityManager.DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT;
260 import static android.app.ActivityManager.RESIZE_MODE_PRESERVE_WINDOW;
261 import static android.app.ActivityManager.StackId.DOCKED_STACK_ID;
262 import static android.app.ActivityManager.StackId.FREEFORM_WORKSPACE_STACK_ID;
263 import static android.app.ActivityManager.StackId.FULLSCREEN_WORKSPACE_STACK_ID;
264 import static android.app.ActivityManager.StackId.HOME_STACK_ID;
265 import static android.app.ActivityManager.StackId.INVALID_STACK_ID;
266 import static android.app.ActivityManager.StackId.PINNED_STACK_ID;
267 import static android.content.pm.PackageManager.FEATURE_FREEFORM_WINDOW_MANAGEMENT;
268 import static android.content.pm.PackageManager.FEATURE_LEANBACK_ONLY;
269 import static android.content.pm.PackageManager.FEATURE_PICTURE_IN_PICTURE;
270 import static android.content.pm.PackageManager.GET_PROVIDERS;
271 import static android.content.pm.PackageManager.MATCH_DEBUG_TRIAGED_MISSING;
272 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_AWARE;
273 import static android.content.pm.PackageManager.MATCH_DIRECT_BOOT_UNAWARE;
274 import static android.content.pm.PackageManager.MATCH_SYSTEM_ONLY;
275 import static android.content.pm.PackageManager.MATCH_UNINSTALLED_PACKAGES;
276 import static android.content.pm.PackageManager.PERMISSION_GRANTED;
277 import static android.content.res.Configuration.UI_MODE_TYPE_TELEVISION;
278 import static android.os.Process.PROC_CHAR;
279 import static android.os.Process.PROC_OUT_LONG;
280 import static android.os.Process.PROC_PARENS;
281 import static android.os.Process.PROC_SPACE_TERM;
282 import static android.provider.Settings.Global.ALWAYS_FINISH_ACTIVITIES;
283 import static android.provider.Settings.Global.DEBUG_APP;
284 import static android.provider.Settings.Global.DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT;
285 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES;
286 import static android.provider.Settings.Global.DEVELOPMENT_FORCE_RTL;
287 import static android.provider.Settings.Global.LENIENT_BACKGROUND_CHECK;
288 import static android.provider.Settings.Global.WAIT_FOR_DEBUGGER;
289 import static android.provider.Settings.System.FONT_SCALE;
290 import static com.android.internal.util.XmlUtils.readBooleanAttribute;
291 import static com.android.internal.util.XmlUtils.readIntAttribute;
292 import static com.android.internal.util.XmlUtils.readLongAttribute;
293 import static com.android.internal.util.XmlUtils.writeBooleanAttribute;
294 import static com.android.internal.util.XmlUtils.writeIntAttribute;
295 import static com.android.internal.util.XmlUtils.writeLongAttribute;
296 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ALL;
297 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_ANR;
298 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BACKUP;
299 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST;
300 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_BACKGROUND;
301 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_BROADCAST_LIGHT;
302 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CLEANUP;
303 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_CONFIGURATION;
304 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_FOCUS;
305 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_IMMERSIVE;
306 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKSCREEN;
307 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LOCKTASK;
308 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_LRU;
309 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_MU;
310 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_OOM_ADJ;
311 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PERMISSIONS_REVIEW;
312 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER;
313 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_POWER_QUICK;
314 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESSES;
315 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROCESS_OBSERVERS;
316 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PROVIDER;
317 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_PSS;
318 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_RECENTS;
319 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SERVICE;
320 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_STACK;
321 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_SWITCH;
322 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_TASKS;
323 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_UID_OBSERVERS;
324 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_URI_PERMISSION;
325 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_USAGE_STATS;
326 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBILITY;
327 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_VISIBLE_BEHIND;
328 import static com.android.server.am.ActivityManagerDebugConfig.DEBUG_WHITELISTS;
329 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BACKUP;
330 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_BROADCAST;
331 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CLEANUP;
332 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_CONFIGURATION;
333 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_FOCUS;
334 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_IMMERSIVE;
335 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKSCREEN;
336 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LOCKTASK;
337 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_LRU;
338 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_MU;
339 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_OOM_ADJ;
340 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_POWER;
341 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESSES;
342 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROCESS_OBSERVERS;
343 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PROVIDER;
344 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_PSS;
345 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_RECENTS;
346 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SERVICE;
347 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_STACK;
348 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_SWITCH;
349 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_UID_OBSERVERS;
350 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_URI_PERMISSION;
351 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBILITY;
352 import static com.android.server.am.ActivityManagerDebugConfig.POSTFIX_VISIBLE_BEHIND;
353 import static com.android.server.am.ActivityManagerDebugConfig.TAG_AM;
354 import static com.android.server.am.ActivityManagerDebugConfig.TAG_WITH_CLASS_NAME;
355 import static com.android.server.am.ActivityRecord.RECENTS_ACTIVITY_TYPE;
356 import static com.android.server.am.ActivityStackSupervisor.ActivityContainer.FORCE_NEW_TASK_FLAGS;
357 import static com.android.server.am.ActivityStackSupervisor.DEFER_RESUME;
358 import static com.android.server.am.ActivityStackSupervisor.FORCE_FOCUS;
359 import static com.android.server.am.ActivityStackSupervisor.ON_TOP;
360 import static com.android.server.am.ActivityStackSupervisor.PRESERVE_WINDOWS;
361 import static com.android.server.am.ActivityStackSupervisor.RESTORE_FROM_RECENTS;
362 import static com.android.server.am.TaskRecord.INVALID_TASK_ID;
363 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_DONT_LOCK;
364 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_LAUNCHABLE_PRIV;
365 import static com.android.server.am.TaskRecord.LOCK_TASK_AUTH_PINNABLE;
366 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_OPEN;
367 import static com.android.server.wm.AppTransition.TRANSIT_ACTIVITY_RELAUNCH;
368 import static com.android.server.wm.AppTransition.TRANSIT_TASK_IN_PLACE;
369 import static com.android.server.wm.AppTransition.TRANSIT_TASK_OPEN;
370 import static com.android.server.wm.AppTransition.TRANSIT_TASK_TO_FRONT;
371 import static org.xmlpull.v1.XmlPullParser.END_DOCUMENT;
372 import static org.xmlpull.v1.XmlPullParser.START_TAG;
373
374 public final class ActivityManagerService extends ActivityManagerNative
375         implements Watchdog.Monitor, BatteryStatsImpl.BatteryCallback {
376
377     private static final String TAG = TAG_WITH_CLASS_NAME ? "ActivityManagerService" : TAG_AM;
378     private static final String TAG_BACKUP = TAG + POSTFIX_BACKUP;
379     private static final String TAG_BROADCAST = TAG + POSTFIX_BROADCAST;
380     private static final String TAG_CLEANUP = TAG + POSTFIX_CLEANUP;
381     private static final String TAG_CONFIGURATION = TAG + POSTFIX_CONFIGURATION;
382     private static final String TAG_FOCUS = TAG + POSTFIX_FOCUS;
383     private static final String TAG_IMMERSIVE = TAG + POSTFIX_IMMERSIVE;
384     private static final String TAG_LOCKSCREEN = TAG + POSTFIX_LOCKSCREEN;
385     private static final String TAG_LOCKTASK = TAG + POSTFIX_LOCKTASK;
386     private static final String TAG_LRU = TAG + POSTFIX_LRU;
387     private static final String TAG_MU = TAG + POSTFIX_MU;
388     private static final String TAG_OOM_ADJ = TAG + POSTFIX_OOM_ADJ;
389     private static final String TAG_POWER = TAG + POSTFIX_POWER;
390     private static final String TAG_PROCESS_OBSERVERS = TAG + POSTFIX_PROCESS_OBSERVERS;
391     private static final String TAG_PROCESSES = TAG + POSTFIX_PROCESSES;
392     private static final String TAG_PROVIDER = TAG + POSTFIX_PROVIDER;
393     private static final String TAG_PSS = TAG + POSTFIX_PSS;
394     private static final String TAG_RECENTS = TAG + POSTFIX_RECENTS;
395     private static final String TAG_SERVICE = TAG + POSTFIX_SERVICE;
396     private static final String TAG_STACK = TAG + POSTFIX_STACK;
397     private static final String TAG_SWITCH = TAG + POSTFIX_SWITCH;
398     private static final String TAG_UID_OBSERVERS = TAG + POSTFIX_UID_OBSERVERS;
399     private static final String TAG_URI_PERMISSION = TAG + POSTFIX_URI_PERMISSION;
400     private static final String TAG_VISIBILITY = TAG + POSTFIX_VISIBILITY;
401     private static final String TAG_VISIBLE_BEHIND = TAG + POSTFIX_VISIBLE_BEHIND;
402
403     // Mock "pretend we're idle now" broadcast action to the job scheduler; declared
404     // here so that while the job scheduler can depend on AMS, the other way around
405     // need not be the case.
406     public static final String ACTION_TRIGGER_IDLE = "com.android.server.ACTION_TRIGGER_IDLE";
407
408     /** Control over CPU and battery monitoring */
409     // write battery stats every 30 minutes.
410     static final long BATTERY_STATS_TIME = 30 * 60 * 1000;
411     static final boolean MONITOR_CPU_USAGE = true;
412     // don't sample cpu less than every 5 seconds.
413     static final long MONITOR_CPU_MIN_TIME = 5 * 1000;
414     // wait possibly forever for next cpu sample.
415     static final long MONITOR_CPU_MAX_TIME = 0x0fffffff;
416     static final boolean MONITOR_THREAD_CPU_USAGE = false;
417
418     // The flags that are set for all calls we make to the package manager.
419     static final int STOCK_PM_FLAGS = PackageManager.GET_SHARED_LIBRARY_FILES;
420
421     static final String SYSTEM_DEBUGGABLE = "ro.debuggable";
422
423     static final boolean IS_USER_BUILD = "user".equals(Build.TYPE);
424
425     // Amount of time after a call to stopAppSwitches() during which we will
426     // prevent further untrusted switches from happening.
427     static final long APP_SWITCH_DELAY_TIME = 5*1000;
428
429     // How long we wait for a launched process to attach to the activity manager
430     // before we decide it's never going to come up for real.
431     static final int PROC_START_TIMEOUT = 10*1000;
432     // How long we wait for an attached process to publish its content providers
433     // before we decide it must be hung.
434     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT = 10*1000;
435
436     // How long we will retain processes hosting content providers in the "last activity"
437     // state before allowing them to drop down to the regular cached LRU list.  This is
438     // to avoid thrashing of provider processes under low memory situations.
439     static final int CONTENT_PROVIDER_RETAIN_TIME = 20*1000;
440
441     // How long we wait for a launched process to attach to the activity manager
442     // before we decide it's never going to come up for real, when the process was
443     // started with a wrapper for instrumentation (such as Valgrind) because it
444     // could take much longer than usual.
445     static final int PROC_START_TIMEOUT_WITH_WRAPPER = 1200*1000;
446
447     // How long to wait after going idle before forcing apps to GC.
448     static final int GC_TIMEOUT = 5*1000;
449
450     // The minimum amount of time between successive GC requests for a process.
451     static final int GC_MIN_INTERVAL = 60*1000;
452
453     // The minimum amount of time between successive PSS requests for a process.
454     static final int FULL_PSS_MIN_INTERVAL = 10*60*1000;
455
456     // The minimum amount of time between successive PSS requests for a process
457     // when the request is due to the memory state being lowered.
458     static final int FULL_PSS_LOWERED_INTERVAL = 2*60*1000;
459
460     // The rate at which we check for apps using excessive power -- 15 mins.
461     static final int POWER_CHECK_DELAY = (DEBUG_POWER_QUICK ? 2 : 15) * 60*1000;
462
463     // The minimum sample duration we will allow before deciding we have
464     // enough data on wake locks to start killing things.
465     static final int WAKE_LOCK_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
466
467     // The minimum sample duration we will allow before deciding we have
468     // enough data on CPU usage to start killing things.
469     static final int CPU_MIN_CHECK_DURATION = (DEBUG_POWER_QUICK ? 1 : 5) * 60*1000;
470
471     // How long we allow a receiver to run before giving up on it.
472     static final int BROADCAST_FG_TIMEOUT = 10*1000;
473     static final int BROADCAST_BG_TIMEOUT = 60*1000;
474
475     // How long we wait until we timeout on key dispatching.
476     static final int KEY_DISPATCHING_TIMEOUT = 5*1000;
477
478     // How long we wait until we timeout on key dispatching during instrumentation.
479     static final int INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT = 60*1000;
480
481     // This is the amount of time an app needs to be running a foreground service before
482     // we will consider it to be doing interaction for usage stats.
483     static final int SERVICE_USAGE_INTERACTION_TIME = 30*60*1000;
484
485     // Maximum amount of time we will allow to elapse before re-reporting usage stats
486     // interaction with foreground processes.
487     static final long USAGE_STATS_INTERACTION_INTERVAL = 24*60*60*1000L;
488
489     // This is the amount of time we allow an app to settle after it goes into the background,
490     // before we start restricting what it can do.
491     static final int BACKGROUND_SETTLE_TIME = 1*60*1000;
492
493     // How long to wait in getAssistContextExtras for the activity and foreground services
494     // to respond with the result.
495     static final int PENDING_ASSIST_EXTRAS_TIMEOUT = 500;
496
497     // How long top wait when going through the modern assist (which doesn't need to block
498     // on getting this result before starting to launch its UI).
499     static final int PENDING_ASSIST_EXTRAS_LONG_TIMEOUT = 2000;
500
501     // Maximum number of persisted Uri grants a package is allowed
502     static final int MAX_PERSISTED_URI_GRANTS = 128;
503
504     static final int MY_PID = Process.myPid();
505
506     static final String[] EMPTY_STRING_ARRAY = new String[0];
507
508     // How many bytes to write into the dropbox log before truncating
509     static final int DROPBOX_MAX_SIZE = 192 * 1024;
510     // Assumes logcat entries average around 100 bytes; that's not perfect stack traces count
511     // as one line, but close enough for now.
512     static final int RESERVED_BYTES_PER_LOGCAT_LINE = 100;
513
514     // Access modes for handleIncomingUser.
515     static final int ALLOW_NON_FULL = 0;
516     static final int ALLOW_NON_FULL_IN_PROFILE = 1;
517     static final int ALLOW_FULL_ONLY = 2;
518
519     // Delay in notifying task stack change listeners (in millis)
520     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY = 100;
521
522     // Necessary ApplicationInfo flags to mark an app as persistent
523     private static final int PERSISTENT_MASK =
524             ApplicationInfo.FLAG_SYSTEM|ApplicationInfo.FLAG_PERSISTENT;
525
526     // Intent sent when remote bugreport collection has been completed
527     private static final String INTENT_REMOTE_BUGREPORT_FINISHED =
528             "android.intent.action.REMOTE_BUGREPORT_FINISHED";
529
530     // Delay to disable app launch boost
531     static final int APP_BOOST_MESSAGE_DELAY = 3000;
532     // Lower delay than APP_BOOST_MESSAGE_DELAY to disable the boost
533     static final int APP_BOOST_TIMEOUT = 2500;
534
535     // Used to indicate that a task is removed it should also be removed from recents.
536     private static final boolean REMOVE_FROM_RECENTS = true;
537     // Used to indicate that an app transition should be animated.
538     static final boolean ANIMATE = true;
539
540     // Determines whether to take full screen screenshots
541     static final boolean TAKE_FULLSCREEN_SCREENSHOTS = true;
542     public static final float FULLSCREEN_SCREENSHOT_SCALE = 0.6f;
543
544     private static native int nativeMigrateToBoost();
545     private static native int nativeMigrateFromBoost();
546     private boolean mIsBoosted = false;
547     private long mBoostStartTime = 0;
548
549     /** All system services */
550     SystemServiceManager mSystemServiceManager;
551
552     private Installer mInstaller;
553
554     /** Run all ActivityStacks through this */
555     final ActivityStackSupervisor mStackSupervisor;
556
557     final ActivityStarter mActivityStarter;
558
559     /** Task stack change listeners. */
560     private final RemoteCallbackList<ITaskStackListener> mTaskStackListeners =
561             new RemoteCallbackList<ITaskStackListener>();
562
563     final InstrumentationReporter mInstrumentationReporter = new InstrumentationReporter();
564
565     public IntentFirewall mIntentFirewall;
566
567     // Whether we should show our dialogs (ANR, crash, etc) or just perform their
568     // default actuion automatically.  Important for devices without direct input
569     // devices.
570     private boolean mShowDialogs = true;
571     private boolean mInVrMode = false;
572
573     // Whether we should use SCHED_FIFO for UI and RenderThreads.
574     private boolean mUseFifoUiScheduling = false;
575
576     BroadcastQueue mFgBroadcastQueue;
577     BroadcastQueue mBgBroadcastQueue;
578     // Convenient for easy iteration over the queues. Foreground is first
579     // so that dispatch of foreground broadcasts gets precedence.
580     final BroadcastQueue[] mBroadcastQueues = new BroadcastQueue[2];
581
582     BroadcastStats mLastBroadcastStats;
583     BroadcastStats mCurBroadcastStats;
584
585     BroadcastQueue broadcastQueueForIntent(Intent intent) {
586         final boolean isFg = (intent.getFlags() & Intent.FLAG_RECEIVER_FOREGROUND) != 0;
587         if (DEBUG_BROADCAST_BACKGROUND) Slog.i(TAG_BROADCAST,
588                 "Broadcast intent " + intent + " on "
589                 + (isFg ? "foreground" : "background") + " queue");
590         return (isFg) ? mFgBroadcastQueue : mBgBroadcastQueue;
591     }
592
593     /**
594      * Activity we have told the window manager to have key focus.
595      */
596     ActivityRecord mFocusedActivity = null;
597
598     /**
599      * User id of the last activity mFocusedActivity was set to.
600      */
601     private int mLastFocusedUserId;
602
603     /**
604      * If non-null, we are tracking the time the user spends in the currently focused app.
605      */
606     private AppTimeTracker mCurAppTimeTracker;
607
608     /**
609      * List of intents that were used to start the most recent tasks.
610      */
611     final RecentTasks mRecentTasks;
612
613     /**
614      * For addAppTask: cached of the last activity component that was added.
615      */
616     ComponentName mLastAddedTaskComponent;
617
618     /**
619      * For addAppTask: cached of the last activity uid that was added.
620      */
621     int mLastAddedTaskUid;
622
623     /**
624      * For addAppTask: cached of the last ActivityInfo that was added.
625      */
626     ActivityInfo mLastAddedTaskActivity;
627
628     /**
629      * List of packages whitelisted by DevicePolicyManager for locktask. Indexed by userId.
630      */
631     SparseArray<String[]> mLockTaskPackages = new SparseArray<>();
632
633     /**
634      * The package name of the DeviceOwner. This package is not permitted to have its data cleared.
635      */
636     String mDeviceOwnerName;
637
638     final UserController mUserController;
639
640     final AppErrors mAppErrors;
641
642     boolean mDoingSetFocusedActivity;
643
644     public boolean canShowErrorDialogs() {
645         return mShowDialogs && !mSleeping && !mShuttingDown
646                 && mLockScreenShown != LOCK_SCREEN_SHOWN;
647     }
648
649     private static final class PriorityState {
650         // Acts as counter for number of synchronized region that needs to acquire 'this' as a lock
651         // the current thread is currently in. When it drops down to zero, we will no longer boost
652         // the thread's priority.
653         private int regionCounter = 0;
654
655         // The thread's previous priority before boosting.
656         private int prevPriority = Integer.MIN_VALUE;
657     }
658
659     static ThreadLocal<PriorityState> sThreadPriorityState = new ThreadLocal<PriorityState>() {
660         @Override protected PriorityState initialValue() {
661             return new PriorityState();
662         }
663     };
664
665     static void boostPriorityForLockedSection() {
666         int tid = Process.myTid();
667         int prevPriority = Process.getThreadPriority(tid);
668         PriorityState state = sThreadPriorityState.get();
669         if (state.regionCounter == 0 && prevPriority > -2) {
670             state.prevPriority = prevPriority;
671             Process.setThreadPriority(tid, -2);
672         }
673         state.regionCounter++;
674     }
675
676     static void resetPriorityAfterLockedSection() {
677         PriorityState state = sThreadPriorityState.get();
678         state.regionCounter--;
679         if (state.regionCounter == 0 && state.prevPriority > -2) {
680             Process.setThreadPriority(Process.myTid(), state.prevPriority);
681         }
682     }
683
684     public class PendingAssistExtras extends Binder implements Runnable {
685         public final ActivityRecord activity;
686         public final Bundle extras;
687         public final Intent intent;
688         public final String hint;
689         public final IResultReceiver receiver;
690         public final int userHandle;
691         public boolean haveResult = false;
692         public Bundle result = null;
693         public AssistStructure structure = null;
694         public AssistContent content = null;
695         public Bundle receiverExtras;
696
697         public PendingAssistExtras(ActivityRecord _activity, Bundle _extras, Intent _intent,
698                 String _hint, IResultReceiver _receiver, Bundle _receiverExtras, int _userHandle) {
699             activity = _activity;
700             extras = _extras;
701             intent = _intent;
702             hint = _hint;
703             receiver = _receiver;
704             receiverExtras = _receiverExtras;
705             userHandle = _userHandle;
706         }
707         @Override
708         public void run() {
709             Slog.w(TAG, "getAssistContextExtras failed: timeout retrieving from " + activity);
710             synchronized (this) {
711                 haveResult = true;
712                 notifyAll();
713             }
714             pendingAssistExtrasTimedOut(this);
715         }
716     }
717
718     final ArrayList<PendingAssistExtras> mPendingAssistExtras
719             = new ArrayList<PendingAssistExtras>();
720
721     /**
722      * Process management.
723      */
724     final ProcessList mProcessList = new ProcessList();
725
726     /**
727      * All of the applications we currently have running organized by name.
728      * The keys are strings of the application package name (as
729      * returned by the package manager), and the keys are ApplicationRecord
730      * objects.
731      */
732     final ProcessMap<ProcessRecord> mProcessNames = new ProcessMap<ProcessRecord>();
733
734     /**
735      * Tracking long-term execution of processes to look for abuse and other
736      * bad app behavior.
737      */
738     final ProcessStatsService mProcessStats;
739
740     /**
741      * The currently running isolated processes.
742      */
743     final SparseArray<ProcessRecord> mIsolatedProcesses = new SparseArray<ProcessRecord>();
744
745     /**
746      * Counter for assigning isolated process uids, to avoid frequently reusing the
747      * same ones.
748      */
749     int mNextIsolatedProcessUid = 0;
750
751     /**
752      * The currently running heavy-weight process, if any.
753      */
754     ProcessRecord mHeavyWeightProcess = null;
755
756     /**
757      * All of the processes we currently have running organized by pid.
758      * The keys are the pid running the application.
759      *
760      * <p>NOTE: This object is protected by its own lock, NOT the global
761      * activity manager lock!
762      */
763     final SparseArray<ProcessRecord> mPidsSelfLocked = new SparseArray<ProcessRecord>();
764
765     /**
766      * All of the processes that have been forced to be foreground.  The key
767      * is the pid of the caller who requested it (we hold a death
768      * link on it).
769      */
770     abstract class ForegroundToken implements IBinder.DeathRecipient {
771         int pid;
772         IBinder token;
773     }
774     final SparseArray<ForegroundToken> mForegroundProcesses = new SparseArray<ForegroundToken>();
775
776     /**
777      * List of records for processes that someone had tried to start before the
778      * system was ready.  We don't start them at that point, but ensure they
779      * are started by the time booting is complete.
780      */
781     final ArrayList<ProcessRecord> mProcessesOnHold = new ArrayList<ProcessRecord>();
782
783     /**
784      * List of persistent applications that are in the process
785      * of being started.
786      */
787     final ArrayList<ProcessRecord> mPersistentStartingProcesses = new ArrayList<ProcessRecord>();
788
789     /**
790      * Processes that are being forcibly torn down.
791      */
792     final ArrayList<ProcessRecord> mRemovedProcesses = new ArrayList<ProcessRecord>();
793
794     /**
795      * List of running applications, sorted by recent usage.
796      * The first entry in the list is the least recently used.
797      */
798     final ArrayList<ProcessRecord> mLruProcesses = new ArrayList<ProcessRecord>();
799
800     /**
801      * Where in mLruProcesses that the processes hosting activities start.
802      */
803     int mLruProcessActivityStart = 0;
804
805     /**
806      * Where in mLruProcesses that the processes hosting services start.
807      * This is after (lower index) than mLruProcessesActivityStart.
808      */
809     int mLruProcessServiceStart = 0;
810
811     /**
812      * List of processes that should gc as soon as things are idle.
813      */
814     final ArrayList<ProcessRecord> mProcessesToGc = new ArrayList<ProcessRecord>();
815
816     /**
817      * Processes we want to collect PSS data from.
818      */
819     final ArrayList<ProcessRecord> mPendingPssProcesses = new ArrayList<ProcessRecord>();
820
821     private boolean mBinderTransactionTrackingEnabled = false;
822
823     /**
824      * Last time we requested PSS data of all processes.
825      */
826     long mLastFullPssTime = SystemClock.uptimeMillis();
827
828     /**
829      * If set, the next time we collect PSS data we should do a full collection
830      * with data from native processes and the kernel.
831      */
832     boolean mFullPssPending = false;
833
834     /**
835      * This is the process holding what we currently consider to be
836      * the "home" activity.
837      */
838     ProcessRecord mHomeProcess;
839
840     /**
841      * This is the process holding the activity the user last visited that
842      * is in a different process from the one they are currently in.
843      */
844     ProcessRecord mPreviousProcess;
845
846     /**
847      * The time at which the previous process was last visible.
848      */
849     long mPreviousProcessVisibleTime;
850
851     /**
852      * Track all uids that have actively running processes.
853      */
854     final SparseArray<UidRecord> mActiveUids = new SparseArray<>();
855
856     /**
857      * This is for verifying the UID report flow.
858      */
859     static final boolean VALIDATE_UID_STATES = true;
860     final SparseArray<UidRecord> mValidateUids = new SparseArray<>();
861
862     /**
863      * Packages that the user has asked to have run in screen size
864      * compatibility mode instead of filling the screen.
865      */
866     final CompatModePackages mCompatModePackages;
867
868     /**
869      * Set of IntentSenderRecord objects that are currently active.
870      */
871     final HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>> mIntentSenderRecords
872             = new HashMap<PendingIntentRecord.Key, WeakReference<PendingIntentRecord>>();
873
874     /**
875      * Fingerprints (hashCode()) of stack traces that we've
876      * already logged DropBox entries for.  Guarded by itself.  If
877      * something (rogue user app) forces this over
878      * MAX_DUP_SUPPRESSED_STACKS entries, the contents are cleared.
879      */
880     private final HashSet<Integer> mAlreadyLoggedViolatedStacks = new HashSet<Integer>();
881     private static final int MAX_DUP_SUPPRESSED_STACKS = 5000;
882
883     /**
884      * Strict Mode background batched logging state.
885      *
886      * The string buffer is guarded by itself, and its lock is also
887      * used to determine if another batched write is already
888      * in-flight.
889      */
890     private final StringBuilder mStrictModeBuffer = new StringBuilder();
891
892     /**
893      * Keeps track of all IIntentReceivers that have been registered for broadcasts.
894      * Hash keys are the receiver IBinder, hash value is a ReceiverList.
895      */
896     final HashMap<IBinder, ReceiverList> mRegisteredReceivers = new HashMap<>();
897
898     /**
899      * Resolver for broadcast intents to registered receivers.
900      * Holds BroadcastFilter (subclass of IntentFilter).
901      */
902     final IntentResolver<BroadcastFilter, BroadcastFilter> mReceiverResolver
903             = new IntentResolver<BroadcastFilter, BroadcastFilter>() {
904         @Override
905         protected boolean allowFilterResult(
906                 BroadcastFilter filter, List<BroadcastFilter> dest) {
907             IBinder target = filter.receiverList.receiver.asBinder();
908             for (int i = dest.size() - 1; i >= 0; i--) {
909                 if (dest.get(i).receiverList.receiver.asBinder() == target) {
910                     return false;
911                 }
912             }
913             return true;
914         }
915
916         @Override
917         protected BroadcastFilter newResult(BroadcastFilter filter, int match, int userId) {
918             if (userId == UserHandle.USER_ALL || filter.owningUserId == UserHandle.USER_ALL
919                     || userId == filter.owningUserId) {
920                 return super.newResult(filter, match, userId);
921             }
922             return null;
923         }
924
925         @Override
926         protected BroadcastFilter[] newArray(int size) {
927             return new BroadcastFilter[size];
928         }
929
930         @Override
931         protected boolean isPackageForFilter(String packageName, BroadcastFilter filter) {
932             return packageName.equals(filter.packageName);
933         }
934     };
935
936     /**
937      * State of all active sticky broadcasts per user.  Keys are the action of the
938      * sticky Intent, values are an ArrayList of all broadcasted intents with
939      * that action (which should usually be one).  The SparseArray is keyed
940      * by the user ID the sticky is for, and can include UserHandle.USER_ALL
941      * for stickies that are sent to all users.
942      */
943     final SparseArray<ArrayMap<String, ArrayList<Intent>>> mStickyBroadcasts =
944             new SparseArray<ArrayMap<String, ArrayList<Intent>>>();
945
946     final ActiveServices mServices;
947
948     final static class Association {
949         final int mSourceUid;
950         final String mSourceProcess;
951         final int mTargetUid;
952         final ComponentName mTargetComponent;
953         final String mTargetProcess;
954
955         int mCount;
956         long mTime;
957
958         int mNesting;
959         long mStartTime;
960
961         // states of the source process when the bind occurred.
962         int mLastState = ActivityManager.MAX_PROCESS_STATE + 1;
963         long mLastStateUptime;
964         long[] mStateTimes = new long[ActivityManager.MAX_PROCESS_STATE
965                 - ActivityManager.MIN_PROCESS_STATE+1];
966
967         Association(int sourceUid, String sourceProcess, int targetUid,
968                 ComponentName targetComponent, String targetProcess) {
969             mSourceUid = sourceUid;
970             mSourceProcess = sourceProcess;
971             mTargetUid = targetUid;
972             mTargetComponent = targetComponent;
973             mTargetProcess = targetProcess;
974         }
975     }
976
977     /**
978      * When service association tracking is enabled, this is all of the associations we
979      * have seen.  Mapping is target uid -> target component -> source uid -> source process name
980      * -> association data.
981      */
982     final SparseArray<ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>>>
983             mAssociations = new SparseArray<>();
984     boolean mTrackingAssociations;
985
986     /**
987      * Backup/restore process management
988      */
989     String mBackupAppName = null;
990     BackupRecord mBackupTarget = null;
991
992     final ProviderMap mProviderMap;
993
994     /**
995      * List of content providers who have clients waiting for them.  The
996      * application is currently being launched and the provider will be
997      * removed from this list once it is published.
998      */
999     final ArrayList<ContentProviderRecord> mLaunchingProviders
1000             = new ArrayList<ContentProviderRecord>();
1001
1002     /**
1003      * File storing persisted {@link #mGrantedUriPermissions}.
1004      */
1005     private final AtomicFile mGrantFile;
1006
1007     /** XML constants used in {@link #mGrantFile} */
1008     private static final String TAG_URI_GRANTS = "uri-grants";
1009     private static final String TAG_URI_GRANT = "uri-grant";
1010     private static final String ATTR_USER_HANDLE = "userHandle";
1011     private static final String ATTR_SOURCE_USER_ID = "sourceUserId";
1012     private static final String ATTR_TARGET_USER_ID = "targetUserId";
1013     private static final String ATTR_SOURCE_PKG = "sourcePkg";
1014     private static final String ATTR_TARGET_PKG = "targetPkg";
1015     private static final String ATTR_URI = "uri";
1016     private static final String ATTR_MODE_FLAGS = "modeFlags";
1017     private static final String ATTR_CREATED_TIME = "createdTime";
1018     private static final String ATTR_PREFIX = "prefix";
1019
1020     /**
1021      * Global set of specific {@link Uri} permissions that have been granted.
1022      * This optimized lookup structure maps from {@link UriPermission#targetUid}
1023      * to {@link UriPermission#uri} to {@link UriPermission}.
1024      */
1025     @GuardedBy("this")
1026     private final SparseArray<ArrayMap<GrantUri, UriPermission>>
1027             mGrantedUriPermissions = new SparseArray<ArrayMap<GrantUri, UriPermission>>();
1028
1029     public static class GrantUri {
1030         public final int sourceUserId;
1031         public final Uri uri;
1032         public boolean prefix;
1033
1034         public GrantUri(int sourceUserId, Uri uri, boolean prefix) {
1035             this.sourceUserId = sourceUserId;
1036             this.uri = uri;
1037             this.prefix = prefix;
1038         }
1039
1040         @Override
1041         public int hashCode() {
1042             int hashCode = 1;
1043             hashCode = 31 * hashCode + sourceUserId;
1044             hashCode = 31 * hashCode + uri.hashCode();
1045             hashCode = 31 * hashCode + (prefix ? 1231 : 1237);
1046             return hashCode;
1047         }
1048
1049         @Override
1050         public boolean equals(Object o) {
1051             if (o instanceof GrantUri) {
1052                 GrantUri other = (GrantUri) o;
1053                 return uri.equals(other.uri) && (sourceUserId == other.sourceUserId)
1054                         && prefix == other.prefix;
1055             }
1056             return false;
1057         }
1058
1059         @Override
1060         public String toString() {
1061             String result = Integer.toString(sourceUserId) + " @ " + uri.toString();
1062             if (prefix) result += " [prefix]";
1063             return result;
1064         }
1065
1066         public String toSafeString() {
1067             String result = Integer.toString(sourceUserId) + " @ " + uri.toSafeString();
1068             if (prefix) result += " [prefix]";
1069             return result;
1070         }
1071
1072         public static GrantUri resolve(int defaultSourceUserHandle, Uri uri) {
1073             return new GrantUri(ContentProvider.getUserIdFromUri(uri, defaultSourceUserHandle),
1074                     ContentProvider.getUriWithoutUserId(uri), false);
1075         }
1076     }
1077
1078     CoreSettingsObserver mCoreSettingsObserver;
1079
1080     FontScaleSettingObserver mFontScaleSettingObserver;
1081
1082     private final class FontScaleSettingObserver extends ContentObserver {
1083         private final Uri mFontScaleUri = Settings.System.getUriFor(FONT_SCALE);
1084
1085         public FontScaleSettingObserver() {
1086             super(mHandler);
1087             ContentResolver resolver = mContext.getContentResolver();
1088             resolver.registerContentObserver(mFontScaleUri, false, this, UserHandle.USER_ALL);
1089         }
1090
1091         @Override
1092         public void onChange(boolean selfChange, Uri uri, @UserIdInt int userId) {
1093             if (mFontScaleUri.equals(uri)) {
1094                 updateFontScaleIfNeeded(userId);
1095             }
1096         }
1097     }
1098
1099     /**
1100      * Thread-local storage used to carry caller permissions over through
1101      * indirect content-provider access.
1102      */
1103     private class Identity {
1104         public final IBinder token;
1105         public final int pid;
1106         public final int uid;
1107
1108         Identity(IBinder _token, int _pid, int _uid) {
1109             token = _token;
1110             pid = _pid;
1111             uid = _uid;
1112         }
1113     }
1114
1115     private static final ThreadLocal<Identity> sCallerIdentity = new ThreadLocal<Identity>();
1116
1117     /**
1118      * All information we have collected about the runtime performance of
1119      * any user id that can impact battery performance.
1120      */
1121     final BatteryStatsService mBatteryStatsService;
1122
1123     /**
1124      * Information about component usage
1125      */
1126     UsageStatsManagerInternal mUsageStatsService;
1127
1128     /**
1129      * Access to DeviceIdleController service.
1130      */
1131     DeviceIdleController.LocalService mLocalDeviceIdleController;
1132
1133     /**
1134      * Information about and control over application operations
1135      */
1136     final AppOpsService mAppOpsService;
1137
1138     /**
1139      * Current configuration information.  HistoryRecord objects are given
1140      * a reference to this object to indicate which configuration they are
1141      * currently running in, so this object must be kept immutable.
1142      */
1143     Configuration mConfiguration = new Configuration();
1144
1145     /**
1146      * Current sequencing integer of the configuration, for skipping old
1147      * configurations.
1148      */
1149     int mConfigurationSeq = 0;
1150
1151     boolean mSuppressResizeConfigChanges = false;
1152
1153     /**
1154      * Hardware-reported OpenGLES version.
1155      */
1156     final int GL_ES_VERSION;
1157
1158     /**
1159      * List of initialization arguments to pass to all processes when binding applications to them.
1160      * For example, references to the commonly used services.
1161      */
1162     HashMap<String, IBinder> mAppBindArgs;
1163     HashMap<String, IBinder> mIsolatedAppBindArgs;
1164
1165     /**
1166      * Temporary to avoid allocations.  Protected by main lock.
1167      */
1168     final StringBuilder mStringBuilder = new StringBuilder(256);
1169
1170     /**
1171      * Used to control how we initialize the service.
1172      */
1173     ComponentName mTopComponent;
1174     String mTopAction = Intent.ACTION_MAIN;
1175     String mTopData;
1176
1177     volatile boolean mProcessesReady = false;
1178     volatile boolean mSystemReady = false;
1179     volatile boolean mOnBattery = false;
1180     volatile int mFactoryTest;
1181
1182     @GuardedBy("this") boolean mBooting = false;
1183     @GuardedBy("this") boolean mCallFinishBooting = false;
1184     @GuardedBy("this") boolean mBootAnimationComplete = false;
1185     @GuardedBy("this") boolean mLaunchWarningShown = false;
1186     @GuardedBy("this") boolean mCheckedForSetup = false;
1187
1188     Context mContext;
1189
1190     /**
1191      * The time at which we will allow normal application switches again,
1192      * after a call to {@link #stopAppSwitches()}.
1193      */
1194     long mAppSwitchesAllowedTime;
1195
1196     /**
1197      * This is set to true after the first switch after mAppSwitchesAllowedTime
1198      * is set; any switches after that will clear the time.
1199      */
1200     boolean mDidAppSwitch;
1201
1202     /**
1203      * Last time (in realtime) at which we checked for power usage.
1204      */
1205     long mLastPowerCheckRealtime;
1206
1207     /**
1208      * Last time (in uptime) at which we checked for power usage.
1209      */
1210     long mLastPowerCheckUptime;
1211
1212     /**
1213      * Set while we are wanting to sleep, to prevent any
1214      * activities from being started/resumed.
1215      */
1216     private boolean mSleeping = false;
1217
1218     /**
1219      * The process state used for processes that are running the top activities.
1220      * This changes between TOP and TOP_SLEEPING to following mSleeping.
1221      */
1222     int mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
1223
1224     /**
1225      * Set while we are running a voice interaction.  This overrides
1226      * sleeping while it is active.
1227      */
1228     private IVoiceInteractionSession mRunningVoice;
1229
1230     /**
1231      * For some direct access we need to power manager.
1232      */
1233     PowerManagerInternal mLocalPowerManager;
1234
1235     /**
1236      * We want to hold a wake lock while running a voice interaction session, since
1237      * this may happen with the screen off and we need to keep the CPU running to
1238      * be able to continue to interact with the user.
1239      */
1240     PowerManager.WakeLock mVoiceWakeLock;
1241
1242     /**
1243      * State of external calls telling us if the device is awake or asleep.
1244      */
1245     private int mWakefulness = PowerManagerInternal.WAKEFULNESS_AWAKE;
1246
1247     /**
1248      * A list of tokens that cause the top activity to be put to sleep.
1249      * They are used by components that may hide and block interaction with underlying
1250      * activities.
1251      */
1252     final ArrayList<SleepToken> mSleepTokens = new ArrayList<SleepToken>();
1253
1254     static final int LOCK_SCREEN_HIDDEN = 0;
1255     static final int LOCK_SCREEN_LEAVING = 1;
1256     static final int LOCK_SCREEN_SHOWN = 2;
1257     /**
1258      * State of external call telling us if the lock screen is shown.
1259      */
1260     int mLockScreenShown = LOCK_SCREEN_HIDDEN;
1261
1262     /**
1263      * Set if we are shutting down the system, similar to sleeping.
1264      */
1265     boolean mShuttingDown = false;
1266
1267     /**
1268      * Current sequence id for oom_adj computation traversal.
1269      */
1270     int mAdjSeq = 0;
1271
1272     /**
1273      * Current sequence id for process LRU updating.
1274      */
1275     int mLruSeq = 0;
1276
1277     /**
1278      * Keep track of the non-cached/empty process we last found, to help
1279      * determine how to distribute cached/empty processes next time.
1280      */
1281     int mNumNonCachedProcs = 0;
1282
1283     /**
1284      * Keep track of the number of cached hidden procs, to balance oom adj
1285      * distribution between those and empty procs.
1286      */
1287     int mNumCachedHiddenProcs = 0;
1288
1289     /**
1290      * Keep track of the number of service processes we last found, to
1291      * determine on the next iteration which should be B services.
1292      */
1293     int mNumServiceProcs = 0;
1294     int mNewNumAServiceProcs = 0;
1295     int mNewNumServiceProcs = 0;
1296
1297     /**
1298      * Allow the current computed overall memory level of the system to go down?
1299      * This is set to false when we are killing processes for reasons other than
1300      * memory management, so that the now smaller process list will not be taken as
1301      * an indication that memory is tighter.
1302      */
1303     boolean mAllowLowerMemLevel = false;
1304
1305     /**
1306      * The last computed memory level, for holding when we are in a state that
1307      * processes are going away for other reasons.
1308      */
1309     int mLastMemoryLevel = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
1310
1311     /**
1312      * The last total number of process we have, to determine if changes actually look
1313      * like a shrinking number of process due to lower RAM.
1314      */
1315     int mLastNumProcesses;
1316
1317     /**
1318      * The uptime of the last time we performed idle maintenance.
1319      */
1320     long mLastIdleTime = SystemClock.uptimeMillis();
1321
1322     /**
1323      * Total time spent with RAM that has been added in the past since the last idle time.
1324      */
1325     long mLowRamTimeSinceLastIdle = 0;
1326
1327     /**
1328      * If RAM is currently low, when that horrible situation started.
1329      */
1330     long mLowRamStartTime = 0;
1331
1332     /**
1333      * For reporting to battery stats the current top application.
1334      */
1335     private String mCurResumedPackage = null;
1336     private int mCurResumedUid = -1;
1337
1338     /**
1339      * For reporting to battery stats the apps currently running foreground
1340      * service.  The ProcessMap is package/uid tuples; each of these contain
1341      * an array of the currently foreground processes.
1342      */
1343     final ProcessMap<ArrayList<ProcessRecord>> mForegroundPackages
1344             = new ProcessMap<ArrayList<ProcessRecord>>();
1345
1346     /**
1347      * This is set if we had to do a delayed dexopt of an app before launching
1348      * it, to increase the ANR timeouts in that case.
1349      */
1350     boolean mDidDexOpt;
1351
1352     /**
1353      * Set if the systemServer made a call to enterSafeMode.
1354      */
1355     boolean mSafeMode;
1356
1357     /**
1358      * If true, we are running under a test environment so will sample PSS from processes
1359      * much more rapidly to try to collect better data when the tests are rapidly
1360      * running through apps.
1361      */
1362     boolean mTestPssMode = false;
1363
1364     String mDebugApp = null;
1365     boolean mWaitForDebugger = false;
1366     boolean mDebugTransient = false;
1367     String mOrigDebugApp = null;
1368     boolean mOrigWaitForDebugger = false;
1369     boolean mAlwaysFinishActivities = false;
1370     boolean mLenientBackgroundCheck = false;
1371     boolean mForceResizableActivities;
1372     boolean mSupportsMultiWindow;
1373     boolean mSupportsFreeformWindowManagement;
1374     boolean mSupportsPictureInPicture;
1375     boolean mSupportsLeanbackOnly;
1376     Rect mDefaultPinnedStackBounds;
1377     IActivityController mController = null;
1378     boolean mControllerIsAMonkey = false;
1379     String mProfileApp = null;
1380     ProcessRecord mProfileProc = null;
1381     String mProfileFile;
1382     ParcelFileDescriptor mProfileFd;
1383     int mSamplingInterval = 0;
1384     boolean mAutoStopProfiler = false;
1385     int mProfileType = 0;
1386     final ProcessMap<Pair<Long, String>> mMemWatchProcesses = new ProcessMap<>();
1387     String mMemWatchDumpProcName;
1388     String mMemWatchDumpFile;
1389     int mMemWatchDumpPid;
1390     int mMemWatchDumpUid;
1391     String mTrackAllocationApp = null;
1392     String mNativeDebuggingApp = null;
1393
1394     final long[] mTmpLong = new long[2];
1395
1396     static final class ProcessChangeItem {
1397         static final int CHANGE_ACTIVITIES = 1<<0;
1398         static final int CHANGE_PROCESS_STATE = 1<<1;
1399         int changes;
1400         int uid;
1401         int pid;
1402         int processState;
1403         boolean foregroundActivities;
1404     }
1405
1406     final RemoteCallbackList<IProcessObserver> mProcessObservers = new RemoteCallbackList<>();
1407     ProcessChangeItem[] mActiveProcessChanges = new ProcessChangeItem[5];
1408
1409     final ArrayList<ProcessChangeItem> mPendingProcessChanges = new ArrayList<>();
1410     final ArrayList<ProcessChangeItem> mAvailProcessChanges = new ArrayList<>();
1411
1412     final RemoteCallbackList<IUidObserver> mUidObservers = new RemoteCallbackList<>();
1413     UidRecord.ChangeItem[] mActiveUidChanges = new UidRecord.ChangeItem[5];
1414
1415     final ArrayList<UidRecord.ChangeItem> mPendingUidChanges = new ArrayList<>();
1416     final ArrayList<UidRecord.ChangeItem> mAvailUidChanges = new ArrayList<>();
1417
1418     /**
1419      * Runtime CPU use collection thread.  This object's lock is used to
1420      * perform synchronization with the thread (notifying it to run).
1421      */
1422     final Thread mProcessCpuThread;
1423
1424     /**
1425      * Used to collect per-process CPU use for ANRs, battery stats, etc.
1426      * Must acquire this object's lock when accessing it.
1427      * NOTE: this lock will be held while doing long operations (trawling
1428      * through all processes in /proc), so it should never be acquired by
1429      * any critical paths such as when holding the main activity manager lock.
1430      */
1431     final ProcessCpuTracker mProcessCpuTracker = new ProcessCpuTracker(
1432             MONITOR_THREAD_CPU_USAGE);
1433     final AtomicLong mLastCpuTime = new AtomicLong(0);
1434     final AtomicBoolean mProcessCpuMutexFree = new AtomicBoolean(true);
1435
1436     long mLastWriteTime = 0;
1437
1438     /**
1439      * Used to retain an update lock when the foreground activity is in
1440      * immersive mode.
1441      */
1442     final UpdateLock mUpdateLock = new UpdateLock("immersive");
1443
1444     /**
1445      * Set to true after the system has finished booting.
1446      */
1447     boolean mBooted = false;
1448
1449     int mProcessLimit = ProcessList.MAX_CACHED_APPS;
1450     int mProcessLimitOverride = -1;
1451
1452     WindowManagerService mWindowManager;
1453     final ActivityThread mSystemThread;
1454
1455     private final class AppDeathRecipient implements IBinder.DeathRecipient {
1456         final ProcessRecord mApp;
1457         final int mPid;
1458         final IApplicationThread mAppThread;
1459
1460         AppDeathRecipient(ProcessRecord app, int pid,
1461                 IApplicationThread thread) {
1462             if (DEBUG_ALL) Slog.v(
1463                 TAG, "New death recipient " + this
1464                 + " for thread " + thread.asBinder());
1465             mApp = app;
1466             mPid = pid;
1467             mAppThread = thread;
1468         }
1469
1470         @Override
1471         public void binderDied() {
1472             if (DEBUG_ALL) Slog.v(
1473                 TAG, "Death received in " + this
1474                 + " for thread " + mAppThread.asBinder());
1475             synchronized(ActivityManagerService.this) {
1476                 appDiedLocked(mApp, mPid, mAppThread, true);
1477             }
1478         }
1479     }
1480
1481     static final int SHOW_ERROR_UI_MSG = 1;
1482     static final int SHOW_NOT_RESPONDING_UI_MSG = 2;
1483     static final int SHOW_FACTORY_ERROR_UI_MSG = 3;
1484     static final int UPDATE_CONFIGURATION_MSG = 4;
1485     static final int GC_BACKGROUND_PROCESSES_MSG = 5;
1486     static final int WAIT_FOR_DEBUGGER_UI_MSG = 6;
1487     static final int SERVICE_TIMEOUT_MSG = 12;
1488     static final int UPDATE_TIME_ZONE = 13;
1489     static final int SHOW_UID_ERROR_UI_MSG = 14;
1490     static final int SHOW_FINGERPRINT_ERROR_UI_MSG = 15;
1491     static final int PROC_START_TIMEOUT_MSG = 20;
1492     static final int DO_PENDING_ACTIVITY_LAUNCHES_MSG = 21;
1493     static final int KILL_APPLICATION_MSG = 22;
1494     static final int FINALIZE_PENDING_INTENT_MSG = 23;
1495     static final int POST_HEAVY_NOTIFICATION_MSG = 24;
1496     static final int CANCEL_HEAVY_NOTIFICATION_MSG = 25;
1497     static final int SHOW_STRICT_MODE_VIOLATION_UI_MSG = 26;
1498     static final int CHECK_EXCESSIVE_WAKE_LOCKS_MSG = 27;
1499     static final int CLEAR_DNS_CACHE_MSG = 28;
1500     static final int UPDATE_HTTP_PROXY_MSG = 29;
1501     static final int SHOW_COMPAT_MODE_DIALOG_UI_MSG = 30;
1502     static final int DISPATCH_PROCESSES_CHANGED_UI_MSG = 31;
1503     static final int DISPATCH_PROCESS_DIED_UI_MSG = 32;
1504     static final int REPORT_MEM_USAGE_MSG = 33;
1505     static final int REPORT_USER_SWITCH_MSG = 34;
1506     static final int CONTINUE_USER_SWITCH_MSG = 35;
1507     static final int USER_SWITCH_TIMEOUT_MSG = 36;
1508     static final int IMMERSIVE_MODE_LOCK_MSG = 37;
1509     static final int PERSIST_URI_GRANTS_MSG = 38;
1510     static final int REQUEST_ALL_PSS_MSG = 39;
1511     static final int START_PROFILES_MSG = 40;
1512     static final int UPDATE_TIME = 41;
1513     static final int SYSTEM_USER_START_MSG = 42;
1514     static final int SYSTEM_USER_CURRENT_MSG = 43;
1515     static final int ENTER_ANIMATION_COMPLETE_MSG = 44;
1516     static final int FINISH_BOOTING_MSG = 45;
1517     static final int START_USER_SWITCH_UI_MSG = 46;
1518     static final int SEND_LOCALE_TO_MOUNT_DAEMON_MSG = 47;
1519     static final int DISMISS_DIALOG_UI_MSG = 48;
1520     static final int NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG = 49;
1521     static final int NOTIFY_CLEARTEXT_NETWORK_MSG = 50;
1522     static final int POST_DUMP_HEAP_NOTIFICATION_MSG = 51;
1523     static final int DELETE_DUMPHEAP_MSG = 52;
1524     static final int FOREGROUND_PROFILE_CHANGED_MSG = 53;
1525     static final int DISPATCH_UIDS_CHANGED_UI_MSG = 54;
1526     static final int REPORT_TIME_TRACKER_MSG = 55;
1527     static final int REPORT_USER_SWITCH_COMPLETE_MSG = 56;
1528     static final int SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG = 57;
1529     static final int APP_BOOST_DEACTIVATE_MSG = 58;
1530     static final int CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG = 59;
1531     static final int IDLE_UIDS_MSG = 60;
1532     static final int SYSTEM_USER_UNLOCK_MSG = 61;
1533     static final int LOG_STACK_STATE = 62;
1534     static final int VR_MODE_CHANGE_MSG = 63;
1535     static final int NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG = 64;
1536     static final int NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG = 65;
1537     static final int NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG = 66;
1538     static final int NOTIFY_FORCED_RESIZABLE_MSG = 67;
1539     static final int NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG = 68;
1540     static final int VR_MODE_APPLY_IF_NEEDED_MSG = 69;
1541     static final int SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG = 70;
1542
1543     static final int FIRST_ACTIVITY_STACK_MSG = 100;
1544     static final int FIRST_BROADCAST_QUEUE_MSG = 200;
1545     static final int FIRST_COMPAT_MODE_MSG = 300;
1546     static final int FIRST_SUPERVISOR_STACK_MSG = 100;
1547
1548     static ServiceThread sKillThread = null;
1549     static KillHandler sKillHandler = null;
1550
1551     CompatModeDialog mCompatModeDialog;
1552     UnsupportedDisplaySizeDialog mUnsupportedDisplaySizeDialog;
1553     long mLastMemUsageReportTime = 0;
1554
1555     /**
1556      * Flag whether the current user is a "monkey", i.e. whether
1557      * the UI is driven by a UI automation tool.
1558      */
1559     private boolean mUserIsMonkey;
1560
1561     /** Flag whether the device has a Recents UI */
1562     boolean mHasRecents;
1563
1564     /** The dimensions of the thumbnails in the Recents UI. */
1565     int mThumbnailWidth;
1566     int mThumbnailHeight;
1567     float mFullscreenThumbnailScale;
1568
1569     final ServiceThread mHandlerThread;
1570     final MainHandler mHandler;
1571     final UiHandler mUiHandler;
1572
1573     PackageManagerInternal mPackageManagerInt;
1574
1575     // VoiceInteraction session ID that changes for each new request except when
1576     // being called for multiwindow assist in a single session.
1577     private int mViSessionId = 1000;
1578
1579     final boolean mPermissionReviewRequired;
1580
1581     final class KillHandler extends Handler {
1582         static final int KILL_PROCESS_GROUP_MSG = 4000;
1583
1584         public KillHandler(Looper looper) {
1585             super(looper, null, true);
1586         }
1587
1588         @Override
1589         public void handleMessage(Message msg) {
1590             switch (msg.what) {
1591                 case KILL_PROCESS_GROUP_MSG:
1592                 {
1593                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "killProcessGroup");
1594                     Process.killProcessGroup(msg.arg1 /* uid */, msg.arg2 /* pid */);
1595                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
1596                 }
1597                 break;
1598
1599                 default:
1600                     super.handleMessage(msg);
1601             }
1602         }
1603     }
1604
1605     final class UiHandler extends Handler {
1606         public UiHandler() {
1607             super(com.android.server.UiThread.get().getLooper(), null, true);
1608         }
1609
1610         @Override
1611         public void handleMessage(Message msg) {
1612             switch (msg.what) {
1613             case SHOW_ERROR_UI_MSG: {
1614                 mAppErrors.handleShowAppErrorUi(msg);
1615                 ensureBootCompleted();
1616             } break;
1617             case SHOW_NOT_RESPONDING_UI_MSG: {
1618                 mAppErrors.handleShowAnrUi(msg);
1619                 ensureBootCompleted();
1620             } break;
1621             case SHOW_STRICT_MODE_VIOLATION_UI_MSG: {
1622                 HashMap<String, Object> data = (HashMap<String, Object>) msg.obj;
1623                 synchronized (ActivityManagerService.this) {
1624                     ProcessRecord proc = (ProcessRecord) data.get("app");
1625                     if (proc == null) {
1626                         Slog.e(TAG, "App not found when showing strict mode dialog.");
1627                         break;
1628                     }
1629                     if (proc.crashDialog != null) {
1630                         Slog.e(TAG, "App already has strict mode dialog: " + proc);
1631                         return;
1632                     }
1633                     AppErrorResult res = (AppErrorResult) data.get("result");
1634                     if (mShowDialogs && !mSleeping && !mShuttingDown) {
1635                         Dialog d = new StrictModeViolationDialog(mContext,
1636                                 ActivityManagerService.this, res, proc);
1637                         d.show();
1638                         proc.crashDialog = d;
1639                     } else {
1640                         // The device is asleep, so just pretend that the user
1641                         // saw a crash dialog and hit "force quit".
1642                         res.set(0);
1643                     }
1644                 }
1645                 ensureBootCompleted();
1646             } break;
1647             case SHOW_FACTORY_ERROR_UI_MSG: {
1648                 Dialog d = new FactoryErrorDialog(
1649                     mContext, msg.getData().getCharSequence("msg"));
1650                 d.show();
1651                 ensureBootCompleted();
1652             } break;
1653             case WAIT_FOR_DEBUGGER_UI_MSG: {
1654                 synchronized (ActivityManagerService.this) {
1655                     ProcessRecord app = (ProcessRecord)msg.obj;
1656                     if (msg.arg1 != 0) {
1657                         if (!app.waitedForDebugger) {
1658                             Dialog d = new AppWaitingForDebuggerDialog(
1659                                     ActivityManagerService.this,
1660                                     mContext, app);
1661                             app.waitDialog = d;
1662                             app.waitedForDebugger = true;
1663                             d.show();
1664                         }
1665                     } else {
1666                         if (app.waitDialog != null) {
1667                             app.waitDialog.dismiss();
1668                             app.waitDialog = null;
1669                         }
1670                     }
1671                 }
1672             } break;
1673             case SHOW_UID_ERROR_UI_MSG: {
1674                 if (mShowDialogs) {
1675                     AlertDialog d = new BaseErrorDialog(mContext);
1676                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1677                     d.setCancelable(false);
1678                     d.setTitle(mContext.getText(R.string.android_system_label));
1679                     d.setMessage(mContext.getText(R.string.system_error_wipe_data));
1680                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1681                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1682                     d.show();
1683                 }
1684             } break;
1685             case SHOW_FINGERPRINT_ERROR_UI_MSG: {
1686                 if (mShowDialogs) {
1687                     AlertDialog d = new BaseErrorDialog(mContext);
1688                     d.getWindow().setType(WindowManager.LayoutParams.TYPE_SYSTEM_ERROR);
1689                     d.setCancelable(false);
1690                     d.setTitle(mContext.getText(R.string.android_system_label));
1691                     d.setMessage(mContext.getText(R.string.system_error_manufacturer));
1692                     d.setButton(DialogInterface.BUTTON_POSITIVE, mContext.getText(R.string.ok),
1693                             obtainMessage(DISMISS_DIALOG_UI_MSG, d));
1694                     d.show();
1695                 }
1696             } break;
1697             case SHOW_COMPAT_MODE_DIALOG_UI_MSG: {
1698                 synchronized (ActivityManagerService.this) {
1699                     ActivityRecord ar = (ActivityRecord) msg.obj;
1700                     if (mCompatModeDialog != null) {
1701                         if (mCompatModeDialog.mAppInfo.packageName.equals(
1702                                 ar.info.applicationInfo.packageName)) {
1703                             return;
1704                         }
1705                         mCompatModeDialog.dismiss();
1706                         mCompatModeDialog = null;
1707                     }
1708                     if (ar != null && false) {
1709                         if (mCompatModePackages.getPackageAskCompatModeLocked(
1710                                 ar.packageName)) {
1711                             int mode = mCompatModePackages.computeCompatModeLocked(
1712                                     ar.info.applicationInfo);
1713                             if (mode == ActivityManager.COMPAT_MODE_DISABLED
1714                                     || mode == ActivityManager.COMPAT_MODE_ENABLED) {
1715                                 mCompatModeDialog = new CompatModeDialog(
1716                                         ActivityManagerService.this, mContext,
1717                                         ar.info.applicationInfo);
1718                                 mCompatModeDialog.show();
1719                             }
1720                         }
1721                     }
1722                 }
1723                 break;
1724             }
1725             case SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG: {
1726                 synchronized (ActivityManagerService.this) {
1727                     final ActivityRecord ar = (ActivityRecord) msg.obj;
1728                     if (mUnsupportedDisplaySizeDialog != null) {
1729                         mUnsupportedDisplaySizeDialog.dismiss();
1730                         mUnsupportedDisplaySizeDialog = null;
1731                     }
1732                     if (ar != null && mCompatModePackages.getPackageNotifyUnsupportedZoomLocked(
1733                             ar.packageName)) {
1734                         mUnsupportedDisplaySizeDialog = new UnsupportedDisplaySizeDialog(
1735                                 ActivityManagerService.this, mContext, ar.info.applicationInfo);
1736                         mUnsupportedDisplaySizeDialog.show();
1737                     }
1738                 }
1739                 break;
1740             }
1741             case START_USER_SWITCH_UI_MSG: {
1742                 mUserController.showUserSwitchDialog((Pair<UserInfo, UserInfo>) msg.obj);
1743                 break;
1744             }
1745             case DISMISS_DIALOG_UI_MSG: {
1746                 final Dialog d = (Dialog) msg.obj;
1747                 d.dismiss();
1748                 break;
1749             }
1750             case DISPATCH_PROCESSES_CHANGED_UI_MSG: {
1751                 dispatchProcessesChanged();
1752                 break;
1753             }
1754             case DISPATCH_PROCESS_DIED_UI_MSG: {
1755                 final int pid = msg.arg1;
1756                 final int uid = msg.arg2;
1757                 dispatchProcessDied(pid, uid);
1758                 break;
1759             }
1760             case DISPATCH_UIDS_CHANGED_UI_MSG: {
1761                 dispatchUidsChanged();
1762             } break;
1763             }
1764         }
1765     }
1766
1767     final class MainHandler extends Handler {
1768         public MainHandler(Looper looper) {
1769             super(looper, null, true);
1770         }
1771
1772         @Override
1773         public void handleMessage(Message msg) {
1774             switch (msg.what) {
1775             case UPDATE_CONFIGURATION_MSG: {
1776                 final ContentResolver resolver = mContext.getContentResolver();
1777                 Settings.System.putConfigurationForUser(resolver, (Configuration) msg.obj,
1778                         msg.arg1);
1779             } break;
1780             case GC_BACKGROUND_PROCESSES_MSG: {
1781                 synchronized (ActivityManagerService.this) {
1782                     performAppGcsIfAppropriateLocked();
1783                 }
1784             } break;
1785             case SERVICE_TIMEOUT_MSG: {
1786                 if (mDidDexOpt) {
1787                     mDidDexOpt = false;
1788                     Message nmsg = mHandler.obtainMessage(SERVICE_TIMEOUT_MSG);
1789                     nmsg.obj = msg.obj;
1790                     mHandler.sendMessageDelayed(nmsg, ActiveServices.SERVICE_TIMEOUT);
1791                     return;
1792                 }
1793                 mServices.serviceTimeout((ProcessRecord)msg.obj);
1794             } break;
1795             case UPDATE_TIME_ZONE: {
1796                 synchronized (ActivityManagerService.this) {
1797                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1798                         ProcessRecord r = mLruProcesses.get(i);
1799                         if (r.thread != null) {
1800                             try {
1801                                 r.thread.updateTimeZone();
1802                             } catch (RemoteException ex) {
1803                                 Slog.w(TAG, "Failed to update time zone for: " + r.info.processName);
1804                             }
1805                         }
1806                     }
1807                 }
1808             } break;
1809             case CLEAR_DNS_CACHE_MSG: {
1810                 synchronized (ActivityManagerService.this) {
1811                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1812                         ProcessRecord r = mLruProcesses.get(i);
1813                         if (r.thread != null) {
1814                             try {
1815                                 r.thread.clearDnsCache();
1816                             } catch (RemoteException ex) {
1817                                 Slog.w(TAG, "Failed to clear dns cache for: " + r.info.processName);
1818                             }
1819                         }
1820                     }
1821                 }
1822             } break;
1823             case UPDATE_HTTP_PROXY_MSG: {
1824                 ProxyInfo proxy = (ProxyInfo)msg.obj;
1825                 String host = "";
1826                 String port = "";
1827                 String exclList = "";
1828                 Uri pacFileUrl = Uri.EMPTY;
1829                 if (proxy != null) {
1830                     host = proxy.getHost();
1831                     port = Integer.toString(proxy.getPort());
1832                     exclList = proxy.getExclusionListAsString();
1833                     pacFileUrl = proxy.getPacFileUrl();
1834                 }
1835                 synchronized (ActivityManagerService.this) {
1836                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
1837                         ProcessRecord r = mLruProcesses.get(i);
1838                         if (r.thread != null) {
1839                             try {
1840                                 r.thread.setHttpProxy(host, port, exclList, pacFileUrl);
1841                             } catch (RemoteException ex) {
1842                                 Slog.w(TAG, "Failed to update http proxy for: " +
1843                                         r.info.processName);
1844                             }
1845                         }
1846                     }
1847                 }
1848             } break;
1849             case PROC_START_TIMEOUT_MSG: {
1850                 if (mDidDexOpt) {
1851                     mDidDexOpt = false;
1852                     Message nmsg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
1853                     nmsg.obj = msg.obj;
1854                     mHandler.sendMessageDelayed(nmsg, PROC_START_TIMEOUT);
1855                     return;
1856                 }
1857                 ProcessRecord app = (ProcessRecord)msg.obj;
1858                 synchronized (ActivityManagerService.this) {
1859                     processStartTimedOutLocked(app);
1860                 }
1861             } break;
1862             case CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG: {
1863                 ProcessRecord app = (ProcessRecord)msg.obj;
1864                 synchronized (ActivityManagerService.this) {
1865                     processContentProviderPublishTimedOutLocked(app);
1866                 }
1867             } break;
1868             case DO_PENDING_ACTIVITY_LAUNCHES_MSG: {
1869                 synchronized (ActivityManagerService.this) {
1870                     mActivityStarter.doPendingActivityLaunchesLocked(true);
1871                 }
1872             } break;
1873             case KILL_APPLICATION_MSG: {
1874                 synchronized (ActivityManagerService.this) {
1875                     final int appId = msg.arg1;
1876                     final int userId = msg.arg2;
1877                     Bundle bundle = (Bundle)msg.obj;
1878                     String pkg = bundle.getString("pkg");
1879                     String reason = bundle.getString("reason");
1880                     forceStopPackageLocked(pkg, appId, false, false, true, false,
1881                             false, userId, reason);
1882                 }
1883             } break;
1884             case FINALIZE_PENDING_INTENT_MSG: {
1885                 ((PendingIntentRecord)msg.obj).completeFinalize();
1886             } break;
1887             case POST_HEAVY_NOTIFICATION_MSG: {
1888                 INotificationManager inm = NotificationManager.getService();
1889                 if (inm == null) {
1890                     return;
1891                 }
1892
1893                 ActivityRecord root = (ActivityRecord)msg.obj;
1894                 ProcessRecord process = root.app;
1895                 if (process == null) {
1896                     return;
1897                 }
1898
1899                 try {
1900                     Context context = mContext.createPackageContext(process.info.packageName, 0);
1901                     String text = mContext.getString(R.string.heavy_weight_notification,
1902                             context.getApplicationInfo().loadLabel(context.getPackageManager()));
1903                     Notification notification = new Notification.Builder(context)
1904                             .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
1905                             .setWhen(0)
1906                             .setOngoing(true)
1907                             .setTicker(text)
1908                             .setColor(mContext.getColor(
1909                                     com.android.internal.R.color.system_notification_accent_color))
1910                             .setContentTitle(text)
1911                             .setContentText(
1912                                     mContext.getText(R.string.heavy_weight_notification_detail))
1913                             .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
1914                                     root.intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
1915                                     new UserHandle(root.userId)))
1916                             .build();
1917                     try {
1918                         int[] outId = new int[1];
1919                         inm.enqueueNotificationWithTag("android", "android", null,
1920                                 R.string.heavy_weight_notification,
1921                                 notification, outId, root.userId);
1922                     } catch (RuntimeException e) {
1923                         Slog.w(ActivityManagerService.TAG,
1924                                 "Error showing notification for heavy-weight app", e);
1925                     } catch (RemoteException e) {
1926                     }
1927                 } catch (NameNotFoundException e) {
1928                     Slog.w(TAG, "Unable to create context for heavy notification", e);
1929                 }
1930             } break;
1931             case CANCEL_HEAVY_NOTIFICATION_MSG: {
1932                 INotificationManager inm = NotificationManager.getService();
1933                 if (inm == null) {
1934                     return;
1935                 }
1936                 try {
1937                     inm.cancelNotificationWithTag("android", null,
1938                             R.string.heavy_weight_notification,  msg.arg1);
1939                 } catch (RuntimeException e) {
1940                     Slog.w(ActivityManagerService.TAG,
1941                             "Error canceling notification for service", e);
1942                 } catch (RemoteException e) {
1943                 }
1944             } break;
1945             case CHECK_EXCESSIVE_WAKE_LOCKS_MSG: {
1946                 synchronized (ActivityManagerService.this) {
1947                     checkExcessivePowerUsageLocked(true);
1948                     removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1949                     Message nmsg = obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
1950                     sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
1951                 }
1952             } break;
1953             case REPORT_MEM_USAGE_MSG: {
1954                 final ArrayList<ProcessMemInfo> memInfos = (ArrayList<ProcessMemInfo>)msg.obj;
1955                 Thread thread = new Thread() {
1956                     @Override public void run() {
1957                         reportMemUsage(memInfos);
1958                     }
1959                 };
1960                 thread.start();
1961                 break;
1962             }
1963             case REPORT_USER_SWITCH_MSG: {
1964                 mUserController.dispatchUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1965                 break;
1966             }
1967             case CONTINUE_USER_SWITCH_MSG: {
1968                 mUserController.continueUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1969                 break;
1970             }
1971             case USER_SWITCH_TIMEOUT_MSG: {
1972                 mUserController.timeoutUserSwitch((UserState) msg.obj, msg.arg1, msg.arg2);
1973                 break;
1974             }
1975             case IMMERSIVE_MODE_LOCK_MSG: {
1976                 final boolean nextState = (msg.arg1 != 0);
1977                 if (mUpdateLock.isHeld() != nextState) {
1978                     if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE,
1979                             "Applying new update lock state '" + nextState
1980                             + "' for " + (ActivityRecord)msg.obj);
1981                     if (nextState) {
1982                         mUpdateLock.acquire();
1983                     } else {
1984                         mUpdateLock.release();
1985                     }
1986                 }
1987                 break;
1988             }
1989             case PERSIST_URI_GRANTS_MSG: {
1990                 writeGrantedUriPermissions();
1991                 break;
1992             }
1993             case REQUEST_ALL_PSS_MSG: {
1994                 synchronized (ActivityManagerService.this) {
1995                     requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, false);
1996                 }
1997                 break;
1998             }
1999             case START_PROFILES_MSG: {
2000                 synchronized (ActivityManagerService.this) {
2001                     mUserController.startProfilesLocked();
2002                 }
2003                 break;
2004             }
2005             case UPDATE_TIME: {
2006                 synchronized (ActivityManagerService.this) {
2007                     for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
2008                         ProcessRecord r = mLruProcesses.get(i);
2009                         if (r.thread != null) {
2010                             try {
2011                                 r.thread.updateTimePrefs(msg.arg1 == 0 ? false : true);
2012                             } catch (RemoteException ex) {
2013                                 Slog.w(TAG, "Failed to update preferences for: " + r.info.processName);
2014                             }
2015                         }
2016                     }
2017                 }
2018                 break;
2019             }
2020             case SYSTEM_USER_START_MSG: {
2021                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
2022                         Integer.toString(msg.arg1), msg.arg1);
2023                 mSystemServiceManager.startUser(msg.arg1);
2024                 break;
2025             }
2026             case SYSTEM_USER_UNLOCK_MSG: {
2027                 final int userId = msg.arg1;
2028                 mSystemServiceManager.unlockUser(userId);
2029                 synchronized (ActivityManagerService.this) {
2030                     mRecentTasks.loadUserRecentsLocked(userId);
2031                 }
2032                 if (userId == UserHandle.USER_SYSTEM) {
2033                     startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_UNAWARE);
2034                 }
2035                 installEncryptionUnawareProviders(userId);
2036                 mUserController.finishUserUnlocked((UserState) msg.obj);
2037                 break;
2038             }
2039             case SYSTEM_USER_CURRENT_MSG: {
2040                 mBatteryStatsService.noteEvent(
2041                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_FINISH,
2042                         Integer.toString(msg.arg2), msg.arg2);
2043                 mBatteryStatsService.noteEvent(
2044                         BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
2045                         Integer.toString(msg.arg1), msg.arg1);
2046                 mSystemServiceManager.switchUser(msg.arg1);
2047                 break;
2048             }
2049             case ENTER_ANIMATION_COMPLETE_MSG: {
2050                 synchronized (ActivityManagerService.this) {
2051                     ActivityRecord r = ActivityRecord.forTokenLocked((IBinder) msg.obj);
2052                     if (r != null && r.app != null && r.app.thread != null) {
2053                         try {
2054                             r.app.thread.scheduleEnterAnimationComplete(r.appToken);
2055                         } catch (RemoteException e) {
2056                         }
2057                     }
2058                 }
2059                 break;
2060             }
2061             case FINISH_BOOTING_MSG: {
2062                 if (msg.arg1 != 0) {
2063                     Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
2064                     finishBooting();
2065                     Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
2066                 }
2067                 if (msg.arg2 != 0) {
2068                     enableScreenAfterBoot();
2069                 }
2070                 break;
2071             }
2072             case SEND_LOCALE_TO_MOUNT_DAEMON_MSG: {
2073                 try {
2074                     Locale l = (Locale) msg.obj;
2075                     IBinder service = ServiceManager.getService("mount");
2076                     IMountService mountService = IMountService.Stub.asInterface(service);
2077                     Log.d(TAG, "Storing locale " + l.toLanguageTag() + " for decryption UI");
2078                     mountService.setField(StorageManager.SYSTEM_LOCALE_KEY, l.toLanguageTag());
2079                 } catch (RemoteException e) {
2080                     Log.e(TAG, "Error storing locale for decryption UI", e);
2081                 }
2082                 break;
2083             }
2084             case NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG: {
2085                 synchronized (ActivityManagerService.this) {
2086                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2087                         try {
2088                             // Make a one-way callback to the listener
2089                             mTaskStackListeners.getBroadcastItem(i).onTaskStackChanged();
2090                         } catch (RemoteException e){
2091                             // Handled by the RemoteCallbackList
2092                         }
2093                     }
2094                     mTaskStackListeners.finishBroadcast();
2095                 }
2096                 break;
2097             }
2098             case NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG: {
2099                 synchronized (ActivityManagerService.this) {
2100                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2101                         try {
2102                             // Make a one-way callback to the listener
2103                             mTaskStackListeners.getBroadcastItem(i).onActivityPinned();
2104                         } catch (RemoteException e){
2105                             // Handled by the RemoteCallbackList
2106                         }
2107                     }
2108                     mTaskStackListeners.finishBroadcast();
2109                 }
2110                 break;
2111             }
2112             case NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG: {
2113                 synchronized (ActivityManagerService.this) {
2114                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2115                         try {
2116                             // Make a one-way callback to the listener
2117                             mTaskStackListeners.getBroadcastItem(i).onPinnedActivityRestartAttempt();
2118                         } catch (RemoteException e){
2119                             // Handled by the RemoteCallbackList
2120                         }
2121                     }
2122                     mTaskStackListeners.finishBroadcast();
2123                 }
2124                 break;
2125             }
2126             case NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG: {
2127                 synchronized (ActivityManagerService.this) {
2128                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2129                         try {
2130                             // Make a one-way callback to the listener
2131                             mTaskStackListeners.getBroadcastItem(i).onPinnedStackAnimationEnded();
2132                         } catch (RemoteException e){
2133                             // Handled by the RemoteCallbackList
2134                         }
2135                     }
2136                     mTaskStackListeners.finishBroadcast();
2137                 }
2138                 break;
2139             }
2140             case NOTIFY_FORCED_RESIZABLE_MSG: {
2141                 synchronized (ActivityManagerService.this) {
2142                     for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2143                         try {
2144                             // Make a one-way callback to the listener
2145                             mTaskStackListeners.getBroadcastItem(i).onActivityForcedResizable(
2146                                     (String) msg.obj, msg.arg1);
2147                         } catch (RemoteException e){
2148                             // Handled by the RemoteCallbackList
2149                         }
2150                     }
2151                     mTaskStackListeners.finishBroadcast();
2152                 }
2153                 break;
2154             }
2155                 case NOTIFY_ACTIVITY_DISMISSING_DOCKED_STACK_MSG: {
2156                     synchronized (ActivityManagerService.this) {
2157                         for (int i = mTaskStackListeners.beginBroadcast() - 1; i >= 0; i--) {
2158                             try {
2159                                 // Make a one-way callback to the listener
2160                                 mTaskStackListeners.getBroadcastItem(i)
2161                                         .onActivityDismissingDockedStack();
2162                             } catch (RemoteException e){
2163                                 // Handled by the RemoteCallbackList
2164                             }
2165                         }
2166                         mTaskStackListeners.finishBroadcast();
2167                     }
2168                     break;
2169                 }
2170             case NOTIFY_CLEARTEXT_NETWORK_MSG: {
2171                 final int uid = msg.arg1;
2172                 final byte[] firstPacket = (byte[]) msg.obj;
2173
2174                 synchronized (mPidsSelfLocked) {
2175                     for (int i = 0; i < mPidsSelfLocked.size(); i++) {
2176                         final ProcessRecord p = mPidsSelfLocked.valueAt(i);
2177                         if (p.uid == uid) {
2178                             try {
2179                                 p.thread.notifyCleartextNetwork(firstPacket);
2180                             } catch (RemoteException ignored) {
2181                             }
2182                         }
2183                     }
2184                 }
2185                 break;
2186             }
2187             case POST_DUMP_HEAP_NOTIFICATION_MSG: {
2188                 final String procName;
2189                 final int uid;
2190                 final long memLimit;
2191                 final String reportPackage;
2192                 synchronized (ActivityManagerService.this) {
2193                     procName = mMemWatchDumpProcName;
2194                     uid = mMemWatchDumpUid;
2195                     Pair<Long, String> val = mMemWatchProcesses.get(procName, uid);
2196                     if (val == null) {
2197                         val = mMemWatchProcesses.get(procName, 0);
2198                     }
2199                     if (val != null) {
2200                         memLimit = val.first;
2201                         reportPackage = val.second;
2202                     } else {
2203                         memLimit = 0;
2204                         reportPackage = null;
2205                     }
2206                 }
2207                 if (procName == null) {
2208                     return;
2209                 }
2210
2211                 if (DEBUG_PSS) Slog.d(TAG_PSS,
2212                         "Showing dump heap notification from " + procName + "/" + uid);
2213
2214                 INotificationManager inm = NotificationManager.getService();
2215                 if (inm == null) {
2216                     return;
2217                 }
2218
2219                 String text = mContext.getString(R.string.dump_heap_notification, procName);
2220
2221
2222                 Intent deleteIntent = new Intent();
2223                 deleteIntent.setAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
2224                 Intent intent = new Intent();
2225                 intent.setClassName("android", DumpHeapActivity.class.getName());
2226                 intent.putExtra(DumpHeapActivity.KEY_PROCESS, procName);
2227                 intent.putExtra(DumpHeapActivity.KEY_SIZE, memLimit);
2228                 if (reportPackage != null) {
2229                     intent.putExtra(DumpHeapActivity.KEY_DIRECT_LAUNCH, reportPackage);
2230                 }
2231                 int userId = UserHandle.getUserId(uid);
2232                 Notification notification = new Notification.Builder(mContext)
2233                         .setSmallIcon(com.android.internal.R.drawable.stat_sys_adb)
2234                         .setWhen(0)
2235                         .setOngoing(true)
2236                         .setAutoCancel(true)
2237                         .setTicker(text)
2238                         .setColor(mContext.getColor(
2239                                 com.android.internal.R.color.system_notification_accent_color))
2240                         .setContentTitle(text)
2241                         .setContentText(
2242                                 mContext.getText(R.string.dump_heap_notification_detail))
2243                         .setContentIntent(PendingIntent.getActivityAsUser(mContext, 0,
2244                                 intent, PendingIntent.FLAG_CANCEL_CURRENT, null,
2245                                 new UserHandle(userId)))
2246                         .setDeleteIntent(PendingIntent.getBroadcastAsUser(mContext, 0,
2247                                 deleteIntent, 0, UserHandle.SYSTEM))
2248                         .build();
2249
2250                 try {
2251                     int[] outId = new int[1];
2252                     inm.enqueueNotificationWithTag("android", "android", null,
2253                             R.string.dump_heap_notification,
2254                             notification, outId, userId);
2255                 } catch (RuntimeException e) {
2256                     Slog.w(ActivityManagerService.TAG,
2257                             "Error showing notification for dump heap", e);
2258                 } catch (RemoteException e) {
2259                 }
2260             } break;
2261             case DELETE_DUMPHEAP_MSG: {
2262                 revokeUriPermission(ActivityThread.currentActivityThread().getApplicationThread(),
2263                         DumpHeapActivity.JAVA_URI,
2264                         Intent.FLAG_GRANT_READ_URI_PERMISSION
2265                                 | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
2266                         UserHandle.myUserId());
2267                 synchronized (ActivityManagerService.this) {
2268                     mMemWatchDumpFile = null;
2269                     mMemWatchDumpProcName = null;
2270                     mMemWatchDumpPid = -1;
2271                     mMemWatchDumpUid = -1;
2272                 }
2273             } break;
2274             case FOREGROUND_PROFILE_CHANGED_MSG: {
2275                 mUserController.dispatchForegroundProfileChanged(msg.arg1);
2276             } break;
2277             case REPORT_TIME_TRACKER_MSG: {
2278                 AppTimeTracker tracker = (AppTimeTracker)msg.obj;
2279                 tracker.deliverResult(mContext);
2280             } break;
2281             case REPORT_USER_SWITCH_COMPLETE_MSG: {
2282                 mUserController.dispatchUserSwitchComplete(msg.arg1);
2283             } break;
2284             case SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG: {
2285                 IUiAutomationConnection connection = (IUiAutomationConnection) msg.obj;
2286                 try {
2287                     connection.shutdown();
2288                 } catch (RemoteException e) {
2289                     Slog.w(TAG, "Error shutting down UiAutomationConnection");
2290                 }
2291                 // Only a UiAutomation can set this flag and now that
2292                 // it is finished we make sure it is reset to its default.
2293                 mUserIsMonkey = false;
2294             } break;
2295             case APP_BOOST_DEACTIVATE_MSG: {
2296                 synchronized(ActivityManagerService.this) {
2297                     if (mIsBoosted) {
2298                         if (mBoostStartTime < (SystemClock.uptimeMillis() - APP_BOOST_TIMEOUT)) {
2299                             nativeMigrateFromBoost();
2300                             mIsBoosted = false;
2301                             mBoostStartTime = 0;
2302                         } else {
2303                             Message newmsg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
2304                             mHandler.sendMessageDelayed(newmsg, APP_BOOST_TIMEOUT);
2305                         }
2306                     }
2307                 }
2308             } break;
2309             case IDLE_UIDS_MSG: {
2310                 idleUids();
2311             } break;
2312             case LOG_STACK_STATE: {
2313                 synchronized (ActivityManagerService.this) {
2314                     mStackSupervisor.logStackState();
2315                 }
2316             } break;
2317             case VR_MODE_CHANGE_MSG: {
2318                 VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
2319                 if (vrService == null) {
2320                     break;
2321                 }
2322                 final ActivityRecord r = (ActivityRecord) msg.obj;
2323                 boolean vrMode;
2324                 ComponentName requestedPackage;
2325                 ComponentName callingPackage;
2326                 int userId;
2327                 synchronized (ActivityManagerService.this) {
2328                     vrMode = r.requestedVrComponent != null;
2329                     requestedPackage = r.requestedVrComponent;
2330                     userId = r.userId;
2331                     callingPackage = r.info.getComponentName();
2332                     if (mInVrMode != vrMode) {
2333                         mInVrMode = vrMode;
2334                         mShowDialogs = shouldShowDialogs(mConfiguration, mInVrMode);
2335                         if (r.app != null) {
2336                             ProcessRecord proc = r.app;
2337                             if (proc.vrThreadTid > 0) {
2338                                 if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
2339                                     try {
2340                                         if (mInVrMode == true) {
2341                                             Process.setThreadScheduler(proc.vrThreadTid,
2342                                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
2343                                         } else {
2344                                             Process.setThreadScheduler(proc.vrThreadTid,
2345                                                 Process.SCHED_OTHER, 0);
2346                                         }
2347                                     } catch (IllegalArgumentException e) {
2348                                         Slog.w(TAG, "Failed to set scheduling policy, thread does"
2349                                                 + " not exist:\n" + e);
2350                                     }
2351                                 }
2352                             }
2353                         }
2354                     }
2355                 }
2356                 vrService.setVrMode(vrMode, requestedPackage, userId, callingPackage);
2357             } break;
2358             case VR_MODE_APPLY_IF_NEEDED_MSG: {
2359                 final ActivityRecord r = (ActivityRecord) msg.obj;
2360                 final boolean needsVrMode = r != null && r.requestedVrComponent != null;
2361                 if (needsVrMode) {
2362                     applyVrMode(msg.arg1 == 1, r.requestedVrComponent, r.userId,
2363                             r.info.getComponentName(), false);
2364                 }
2365             } break;
2366             }
2367         }
2368     };
2369
2370     static final int COLLECT_PSS_BG_MSG = 1;
2371
2372     final Handler mBgHandler = new Handler(BackgroundThread.getHandler().getLooper()) {
2373         @Override
2374         public void handleMessage(Message msg) {
2375             switch (msg.what) {
2376             case COLLECT_PSS_BG_MSG: {
2377                 long start = SystemClock.uptimeMillis();
2378                 MemInfoReader memInfo = null;
2379                 synchronized (ActivityManagerService.this) {
2380                     if (mFullPssPending) {
2381                         mFullPssPending = false;
2382                         memInfo = new MemInfoReader();
2383                     }
2384                 }
2385                 if (memInfo != null) {
2386                     updateCpuStatsNow();
2387                     long nativeTotalPss = 0;
2388                     final List<ProcessCpuTracker.Stats> stats;
2389                     synchronized (mProcessCpuTracker) {
2390                         stats = mProcessCpuTracker.getStats( (st)-> {
2391                             return st.vsize > 0 && st.uid < Process.FIRST_APPLICATION_UID;
2392                         });
2393                     }
2394                     final int N = stats.size();
2395                     for (int j = 0; j < N; j++) {
2396                         synchronized (mPidsSelfLocked) {
2397                             if (mPidsSelfLocked.indexOfKey(stats.get(j).pid) >= 0) {
2398                                 // This is one of our own processes; skip it.
2399                                 continue;
2400                             }
2401                         }
2402                         nativeTotalPss += Debug.getPss(stats.get(j).pid, null, null);
2403                     }
2404                     memInfo.readMemInfo();
2405                     synchronized (ActivityManagerService.this) {
2406                         if (DEBUG_PSS) Slog.d(TAG_PSS, "Collected native and kernel memory in "
2407                                 + (SystemClock.uptimeMillis()-start) + "ms");
2408                         final long cachedKb = memInfo.getCachedSizeKb();
2409                         final long freeKb = memInfo.getFreeSizeKb();
2410                         final long zramKb = memInfo.getZramTotalSizeKb();
2411                         final long kernelKb = memInfo.getKernelUsedSizeKb();
2412                         EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
2413                                 kernelKb*1024, nativeTotalPss*1024);
2414                         mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
2415                                 nativeTotalPss);
2416                     }
2417                 }
2418
2419                 int num = 0;
2420                 long[] tmp = new long[2];
2421                 do {
2422                     ProcessRecord proc;
2423                     int procState;
2424                     int pid;
2425                     long lastPssTime;
2426                     synchronized (ActivityManagerService.this) {
2427                         if (mPendingPssProcesses.size() <= 0) {
2428                             if (mTestPssMode || DEBUG_PSS) Slog.d(TAG_PSS,
2429                                     "Collected PSS of " + num + " processes in "
2430                                     + (SystemClock.uptimeMillis() - start) + "ms");
2431                             mPendingPssProcesses.clear();
2432                             return;
2433                         }
2434                         proc = mPendingPssProcesses.remove(0);
2435                         procState = proc.pssProcState;
2436                         lastPssTime = proc.lastPssTime;
2437                         if (proc.thread != null && procState == proc.setProcState
2438                                 && (lastPssTime+ProcessList.PSS_SAFE_TIME_FROM_STATE_CHANGE)
2439                                         < SystemClock.uptimeMillis()) {
2440                             pid = proc.pid;
2441                         } else {
2442                             proc = null;
2443                             pid = 0;
2444                         }
2445                     }
2446                     if (proc != null) {
2447                         long pss = Debug.getPss(pid, tmp, null);
2448                         synchronized (ActivityManagerService.this) {
2449                             if (pss != 0 && proc.thread != null && proc.setProcState == procState
2450                                     && proc.pid == pid && proc.lastPssTime == lastPssTime) {
2451                                 num++;
2452                                 recordPssSampleLocked(proc, procState, pss, tmp[0], tmp[1],
2453                                         SystemClock.uptimeMillis());
2454                             }
2455                         }
2456                     }
2457                 } while (true);
2458             }
2459             }
2460         }
2461     };
2462
2463     public void setSystemProcess() {
2464         try {
2465             ServiceManager.addService(Context.ACTIVITY_SERVICE, this, true);
2466             ServiceManager.addService(ProcessStats.SERVICE_NAME, mProcessStats);
2467             ServiceManager.addService("meminfo", new MemBinder(this));
2468             ServiceManager.addService("gfxinfo", new GraphicsBinder(this));
2469             ServiceManager.addService("dbinfo", new DbBinder(this));
2470             if (MONITOR_CPU_USAGE) {
2471                 ServiceManager.addService("cpuinfo", new CpuBinder(this));
2472             }
2473             ServiceManager.addService("permission", new PermissionController(this));
2474             ServiceManager.addService("processinfo", new ProcessInfoService(this));
2475
2476             ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
2477                     "android", STOCK_PM_FLAGS | MATCH_SYSTEM_ONLY);
2478             mSystemThread.installSystemApplicationInfo(info, getClass().getClassLoader());
2479
2480             synchronized (this) {
2481                 ProcessRecord app = newProcessRecordLocked(info, info.processName, false, 0);
2482                 app.persistent = true;
2483                 app.pid = MY_PID;
2484                 app.maxAdj = ProcessList.SYSTEM_ADJ;
2485                 app.makeActive(mSystemThread.getApplicationThread(), mProcessStats);
2486                 synchronized (mPidsSelfLocked) {
2487                     mPidsSelfLocked.put(app.pid, app);
2488                 }
2489                 updateLruProcessLocked(app, false, null);
2490                 updateOomAdjLocked();
2491             }
2492         } catch (PackageManager.NameNotFoundException e) {
2493             throw new RuntimeException(
2494                     "Unable to find android system package", e);
2495         }
2496     }
2497
2498     public void setWindowManager(WindowManagerService wm) {
2499         mWindowManager = wm;
2500         mStackSupervisor.setWindowManager(wm);
2501         mActivityStarter.setWindowManager(wm);
2502     }
2503
2504     public void setUsageStatsManager(UsageStatsManagerInternal usageStatsManager) {
2505         mUsageStatsService = usageStatsManager;
2506     }
2507
2508     public void startObservingNativeCrashes() {
2509         final NativeCrashListener ncl = new NativeCrashListener(this);
2510         ncl.start();
2511     }
2512
2513     public IAppOpsService getAppOpsService() {
2514         return mAppOpsService;
2515     }
2516
2517     static class MemBinder extends Binder {
2518         ActivityManagerService mActivityManagerService;
2519         MemBinder(ActivityManagerService activityManagerService) {
2520             mActivityManagerService = activityManagerService;
2521         }
2522
2523         @Override
2524         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2525             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2526                     != PackageManager.PERMISSION_GRANTED) {
2527                 pw.println("Permission Denial: can't dump meminfo from from pid="
2528                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2529                         + " without permission " + android.Manifest.permission.DUMP);
2530                 return;
2531             }
2532
2533             mActivityManagerService.dumpApplicationMemoryUsage(fd, pw, "  ", args, false, null);
2534         }
2535     }
2536
2537     static class GraphicsBinder extends Binder {
2538         ActivityManagerService mActivityManagerService;
2539         GraphicsBinder(ActivityManagerService activityManagerService) {
2540             mActivityManagerService = activityManagerService;
2541         }
2542
2543         @Override
2544         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2545             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2546                     != PackageManager.PERMISSION_GRANTED) {
2547                 pw.println("Permission Denial: can't dump gfxinfo from from pid="
2548                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2549                         + " without permission " + android.Manifest.permission.DUMP);
2550                 return;
2551             }
2552
2553             mActivityManagerService.dumpGraphicsHardwareUsage(fd, pw, args);
2554         }
2555     }
2556
2557     static class DbBinder extends Binder {
2558         ActivityManagerService mActivityManagerService;
2559         DbBinder(ActivityManagerService activityManagerService) {
2560             mActivityManagerService = activityManagerService;
2561         }
2562
2563         @Override
2564         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2565             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2566                     != PackageManager.PERMISSION_GRANTED) {
2567                 pw.println("Permission Denial: can't dump dbinfo from from pid="
2568                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2569                         + " without permission " + android.Manifest.permission.DUMP);
2570                 return;
2571             }
2572
2573             mActivityManagerService.dumpDbInfo(fd, pw, args);
2574         }
2575     }
2576
2577     static class CpuBinder extends Binder {
2578         ActivityManagerService mActivityManagerService;
2579         CpuBinder(ActivityManagerService activityManagerService) {
2580             mActivityManagerService = activityManagerService;
2581         }
2582
2583         @Override
2584         protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
2585             if (mActivityManagerService.checkCallingPermission(android.Manifest.permission.DUMP)
2586                     != PackageManager.PERMISSION_GRANTED) {
2587                 pw.println("Permission Denial: can't dump cpuinfo from from pid="
2588                         + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
2589                         + " without permission " + android.Manifest.permission.DUMP);
2590                 return;
2591             }
2592
2593             synchronized (mActivityManagerService.mProcessCpuTracker) {
2594                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentLoad());
2595                 pw.print(mActivityManagerService.mProcessCpuTracker.printCurrentState(
2596                         SystemClock.uptimeMillis()));
2597             }
2598         }
2599     }
2600
2601     public static final class Lifecycle extends SystemService {
2602         private final ActivityManagerService mService;
2603
2604         public Lifecycle(Context context) {
2605             super(context);
2606             mService = new ActivityManagerService(context);
2607         }
2608
2609         @Override
2610         public void onStart() {
2611             mService.start();
2612         }
2613
2614         public ActivityManagerService getService() {
2615             return mService;
2616         }
2617     }
2618
2619     // Note: This method is invoked on the main thread but may need to attach various
2620     // handlers to other threads.  So take care to be explicit about the looper.
2621     public ActivityManagerService(Context systemContext) {
2622         mContext = systemContext;
2623         mFactoryTest = FactoryTest.getMode();
2624         mSystemThread = ActivityThread.currentActivityThread();
2625
2626         Slog.i(TAG, "Memory class: " + ActivityManager.staticGetMemoryClass());
2627
2628         mPermissionReviewRequired = mContext.getResources().getBoolean(
2629                 com.android.internal.R.bool.config_permissionReviewRequired);
2630
2631         mHandlerThread = new ServiceThread(TAG,
2632                 android.os.Process.THREAD_PRIORITY_FOREGROUND, false /*allowIo*/);
2633         mHandlerThread.start();
2634         mHandler = new MainHandler(mHandlerThread.getLooper());
2635         mUiHandler = new UiHandler();
2636
2637         /* static; one-time init here */
2638         if (sKillHandler == null) {
2639             sKillThread = new ServiceThread(TAG + ":kill",
2640                     android.os.Process.THREAD_PRIORITY_BACKGROUND, true /* allowIo */);
2641             sKillThread.start();
2642             sKillHandler = new KillHandler(sKillThread.getLooper());
2643         }
2644
2645         mFgBroadcastQueue = new BroadcastQueue(this, mHandler,
2646                 "foreground", BROADCAST_FG_TIMEOUT, false);
2647         mBgBroadcastQueue = new BroadcastQueue(this, mHandler,
2648                 "background", BROADCAST_BG_TIMEOUT, true);
2649         mBroadcastQueues[0] = mFgBroadcastQueue;
2650         mBroadcastQueues[1] = mBgBroadcastQueue;
2651
2652         mServices = new ActiveServices(this);
2653         mProviderMap = new ProviderMap(this);
2654         mAppErrors = new AppErrors(mContext, this);
2655
2656         // TODO: Move creation of battery stats service outside of activity manager service.
2657         File dataDir = Environment.getDataDirectory();
2658         File systemDir = new File(dataDir, "system");
2659         systemDir.mkdirs();
2660         mBatteryStatsService = new BatteryStatsService(systemDir, mHandler);
2661         mBatteryStatsService.getActiveStatistics().readLocked();
2662         mBatteryStatsService.scheduleWriteToDisk();
2663         mOnBattery = DEBUG_POWER ? true
2664                 : mBatteryStatsService.getActiveStatistics().getIsOnBattery();
2665         mBatteryStatsService.getActiveStatistics().setCallback(this);
2666
2667         mProcessStats = new ProcessStatsService(this, new File(systemDir, "procstats"));
2668
2669         mAppOpsService = new AppOpsService(new File(systemDir, "appops.xml"), mHandler);
2670         mAppOpsService.startWatchingMode(AppOpsManager.OP_RUN_IN_BACKGROUND, null,
2671                 new IAppOpsCallback.Stub() {
2672                     @Override public void opChanged(int op, int uid, String packageName) {
2673                         if (op == AppOpsManager.OP_RUN_IN_BACKGROUND && packageName != null) {
2674                             if (mAppOpsService.checkOperation(op, uid, packageName)
2675                                     != AppOpsManager.MODE_ALLOWED) {
2676                                 runInBackgroundDisabled(uid);
2677                             }
2678                         }
2679                     }
2680                 });
2681
2682         mGrantFile = new AtomicFile(new File(systemDir, "urigrants.xml"));
2683
2684         mUserController = new UserController(this);
2685
2686         GL_ES_VERSION = SystemProperties.getInt("ro.opengles.version",
2687             ConfigurationInfo.GL_ES_VERSION_UNDEFINED);
2688
2689         if (SystemProperties.getInt("sys.use_fifo_ui", 0) != 0) {
2690             mUseFifoUiScheduling = true;
2691         }
2692
2693         mTrackingAssociations = "1".equals(SystemProperties.get("debug.track-associations"));
2694
2695         mConfiguration.setToDefaults();
2696         mConfiguration.setLocales(LocaleList.getDefault());
2697
2698         mConfigurationSeq = mConfiguration.seq = 1;
2699         mProcessCpuTracker.init();
2700
2701         mCompatModePackages = new CompatModePackages(this, systemDir, mHandler);
2702         mIntentFirewall = new IntentFirewall(new IntentFirewallInterface(), mHandler);
2703         mStackSupervisor = new ActivityStackSupervisor(this);
2704         mActivityStarter = new ActivityStarter(this, mStackSupervisor);
2705         mRecentTasks = new RecentTasks(this, mStackSupervisor);
2706
2707         mProcessCpuThread = new Thread("CpuTracker") {
2708             @Override
2709             public void run() {
2710                 while (true) {
2711                     try {
2712                         try {
2713                             synchronized(this) {
2714                                 final long now = SystemClock.uptimeMillis();
2715                                 long nextCpuDelay = (mLastCpuTime.get()+MONITOR_CPU_MAX_TIME)-now;
2716                                 long nextWriteDelay = (mLastWriteTime+BATTERY_STATS_TIME)-now;
2717                                 //Slog.i(TAG, "Cpu delay=" + nextCpuDelay
2718                                 //        + ", write delay=" + nextWriteDelay);
2719                                 if (nextWriteDelay < nextCpuDelay) {
2720                                     nextCpuDelay = nextWriteDelay;
2721                                 }
2722                                 if (nextCpuDelay > 0) {
2723                                     mProcessCpuMutexFree.set(true);
2724                                     this.wait(nextCpuDelay);
2725                                 }
2726                             }
2727                         } catch (InterruptedException e) {
2728                         }
2729                         updateCpuStatsNow();
2730                     } catch (Exception e) {
2731                         Slog.e(TAG, "Unexpected exception collecting process stats", e);
2732                     }
2733                 }
2734             }
2735         };
2736
2737         Watchdog.getInstance().addMonitor(this);
2738         Watchdog.getInstance().addThread(mHandler);
2739     }
2740
2741     public void setSystemServiceManager(SystemServiceManager mgr) {
2742         mSystemServiceManager = mgr;
2743     }
2744
2745     public void setInstaller(Installer installer) {
2746         mInstaller = installer;
2747     }
2748
2749     private void start() {
2750         Process.removeAllProcessGroups();
2751         mProcessCpuThread.start();
2752
2753         mBatteryStatsService.publish(mContext);
2754         mAppOpsService.publish(mContext);
2755         Slog.d("AppOps", "AppOpsService published");
2756         LocalServices.addService(ActivityManagerInternal.class, new LocalService());
2757     }
2758
2759     void onUserStoppedLocked(int userId) {
2760         mRecentTasks.unloadUserDataFromMemoryLocked(userId);
2761     }
2762
2763     public void initPowerManagement() {
2764         mStackSupervisor.initPowerManagement();
2765         mBatteryStatsService.initPowerManagement();
2766         mLocalPowerManager = LocalServices.getService(PowerManagerInternal.class);
2767         PowerManager pm = (PowerManager)mContext.getSystemService(Context.POWER_SERVICE);
2768         mVoiceWakeLock = pm.newWakeLock(PowerManager.PARTIAL_WAKE_LOCK, "*voice*");
2769         mVoiceWakeLock.setReferenceCounted(false);
2770     }
2771
2772     @Override
2773     public boolean onTransact(int code, Parcel data, Parcel reply, int flags)
2774             throws RemoteException {
2775         if (code == SYSPROPS_TRANSACTION) {
2776             // We need to tell all apps about the system property change.
2777             ArrayList<IBinder> procs = new ArrayList<IBinder>();
2778             synchronized(this) {
2779                 final int NP = mProcessNames.getMap().size();
2780                 for (int ip=0; ip<NP; ip++) {
2781                     SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
2782                     final int NA = apps.size();
2783                     for (int ia=0; ia<NA; ia++) {
2784                         ProcessRecord app = apps.valueAt(ia);
2785                         if (app.thread != null) {
2786                             procs.add(app.thread.asBinder());
2787                         }
2788                     }
2789                 }
2790             }
2791
2792             int N = procs.size();
2793             for (int i=0; i<N; i++) {
2794                 Parcel data2 = Parcel.obtain();
2795                 try {
2796                     procs.get(i).transact(IBinder.SYSPROPS_TRANSACTION, data2, null, 0);
2797                 } catch (RemoteException e) {
2798                 }
2799                 data2.recycle();
2800             }
2801         }
2802         try {
2803             return super.onTransact(code, data, reply, flags);
2804         } catch (RuntimeException e) {
2805             // The activity manager only throws security exceptions, so let's
2806             // log all others.
2807             if (!(e instanceof SecurityException)) {
2808                 Slog.wtf(TAG, "Activity Manager Crash", e);
2809             }
2810             throw e;
2811         }
2812     }
2813
2814     void updateCpuStats() {
2815         final long now = SystemClock.uptimeMillis();
2816         if (mLastCpuTime.get() >= now - MONITOR_CPU_MIN_TIME) {
2817             return;
2818         }
2819         if (mProcessCpuMutexFree.compareAndSet(true, false)) {
2820             synchronized (mProcessCpuThread) {
2821                 mProcessCpuThread.notify();
2822             }
2823         }
2824     }
2825
2826     void updateCpuStatsNow() {
2827         synchronized (mProcessCpuTracker) {
2828             mProcessCpuMutexFree.set(false);
2829             final long now = SystemClock.uptimeMillis();
2830             boolean haveNewCpuStats = false;
2831
2832             if (MONITOR_CPU_USAGE &&
2833                     mLastCpuTime.get() < (now-MONITOR_CPU_MIN_TIME)) {
2834                 mLastCpuTime.set(now);
2835                 mProcessCpuTracker.update();
2836                 if (mProcessCpuTracker.hasGoodLastStats()) {
2837                     haveNewCpuStats = true;
2838                     //Slog.i(TAG, mProcessCpu.printCurrentState());
2839                     //Slog.i(TAG, "Total CPU usage: "
2840                     //        + mProcessCpu.getTotalCpuPercent() + "%");
2841
2842                     // Slog the cpu usage if the property is set.
2843                     if ("true".equals(SystemProperties.get("events.cpu"))) {
2844                         int user = mProcessCpuTracker.getLastUserTime();
2845                         int system = mProcessCpuTracker.getLastSystemTime();
2846                         int iowait = mProcessCpuTracker.getLastIoWaitTime();
2847                         int irq = mProcessCpuTracker.getLastIrqTime();
2848                         int softIrq = mProcessCpuTracker.getLastSoftIrqTime();
2849                         int idle = mProcessCpuTracker.getLastIdleTime();
2850
2851                         int total = user + system + iowait + irq + softIrq + idle;
2852                         if (total == 0) total = 1;
2853
2854                         EventLog.writeEvent(EventLogTags.CPU,
2855                                 ((user+system+iowait+irq+softIrq) * 100) / total,
2856                                 (user * 100) / total,
2857                                 (system * 100) / total,
2858                                 (iowait * 100) / total,
2859                                 (irq * 100) / total,
2860                                 (softIrq * 100) / total);
2861                     }
2862                 }
2863             }
2864
2865             final BatteryStatsImpl bstats = mBatteryStatsService.getActiveStatistics();
2866             synchronized(bstats) {
2867                 synchronized(mPidsSelfLocked) {
2868                     if (haveNewCpuStats) {
2869                         if (bstats.startAddingCpuLocked()) {
2870                             int totalUTime = 0;
2871                             int totalSTime = 0;
2872                             final int N = mProcessCpuTracker.countStats();
2873                             for (int i=0; i<N; i++) {
2874                                 ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
2875                                 if (!st.working) {
2876                                     continue;
2877                                 }
2878                                 ProcessRecord pr = mPidsSelfLocked.get(st.pid);
2879                                 totalUTime += st.rel_utime;
2880                                 totalSTime += st.rel_stime;
2881                                 if (pr != null) {
2882                                     BatteryStatsImpl.Uid.Proc ps = pr.curProcBatteryStats;
2883                                     if (ps == null || !ps.isActive()) {
2884                                         pr.curProcBatteryStats = ps = bstats.getProcessStatsLocked(
2885                                                 pr.info.uid, pr.processName);
2886                                     }
2887                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2888                                     pr.curCpuTime += st.rel_utime + st.rel_stime;
2889                                 } else {
2890                                     BatteryStatsImpl.Uid.Proc ps = st.batteryStats;
2891                                     if (ps == null || !ps.isActive()) {
2892                                         st.batteryStats = ps = bstats.getProcessStatsLocked(
2893                                                 bstats.mapUid(st.uid), st.name);
2894                                     }
2895                                     ps.addCpuTimeLocked(st.rel_utime, st.rel_stime);
2896                                 }
2897                             }
2898                             final int userTime = mProcessCpuTracker.getLastUserTime();
2899                             final int systemTime = mProcessCpuTracker.getLastSystemTime();
2900                             final int iowaitTime = mProcessCpuTracker.getLastIoWaitTime();
2901                             final int irqTime = mProcessCpuTracker.getLastIrqTime();
2902                             final int softIrqTime = mProcessCpuTracker.getLastSoftIrqTime();
2903                             final int idleTime = mProcessCpuTracker.getLastIdleTime();
2904                             bstats.finishAddingCpuLocked(totalUTime, totalSTime, userTime,
2905                                     systemTime, iowaitTime, irqTime, softIrqTime, idleTime);
2906                         }
2907                     }
2908                 }
2909
2910                 if (mLastWriteTime < (now-BATTERY_STATS_TIME)) {
2911                     mLastWriteTime = now;
2912                     mBatteryStatsService.scheduleWriteToDisk();
2913                 }
2914             }
2915         }
2916     }
2917
2918     @Override
2919     public void batteryNeedsCpuUpdate() {
2920         updateCpuStatsNow();
2921     }
2922
2923     @Override
2924     public void batteryPowerChanged(boolean onBattery) {
2925         // When plugging in, update the CPU stats first before changing
2926         // the plug state.
2927         updateCpuStatsNow();
2928         synchronized (this) {
2929             synchronized(mPidsSelfLocked) {
2930                 mOnBattery = DEBUG_POWER ? true : onBattery;
2931             }
2932         }
2933     }
2934
2935     @Override
2936     public void batterySendBroadcast(Intent intent) {
2937         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
2938                 AppOpsManager.OP_NONE, null, false, false,
2939                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
2940     }
2941
2942     /**
2943      * Initialize the application bind args. These are passed to each
2944      * process when the bindApplication() IPC is sent to the process. They're
2945      * lazily setup to make sure the services are running when they're asked for.
2946      */
2947     private HashMap<String, IBinder> getCommonServicesLocked(boolean isolated) {
2948         // Isolated processes won't get this optimization, so that we don't
2949         // violate the rules about which services they have access to.
2950         if (isolated) {
2951             if (mIsolatedAppBindArgs == null) {
2952                 mIsolatedAppBindArgs = new HashMap<>();
2953                 mIsolatedAppBindArgs.put("package", ServiceManager.getService("package"));
2954             }
2955             return mIsolatedAppBindArgs;
2956         }
2957
2958         if (mAppBindArgs == null) {
2959             mAppBindArgs = new HashMap<>();
2960
2961             // Setup the application init args
2962             mAppBindArgs.put("package", ServiceManager.getService("package"));
2963             mAppBindArgs.put("window", ServiceManager.getService("window"));
2964             mAppBindArgs.put(Context.ALARM_SERVICE,
2965                     ServiceManager.getService(Context.ALARM_SERVICE));
2966         }
2967         return mAppBindArgs;
2968     }
2969
2970     boolean setFocusedActivityLocked(ActivityRecord r, String reason) {
2971         if (r == null || mFocusedActivity == r) {
2972             return false;
2973         }
2974
2975         if (!r.isFocusable()) {
2976             if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: unfocusable r=" + r);
2977             return false;
2978         }
2979
2980         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedActivityLocked: r=" + r);
2981
2982         final boolean wasDoingSetFocusedActivity = mDoingSetFocusedActivity;
2983         if (wasDoingSetFocusedActivity) Slog.w(TAG,
2984                 "setFocusedActivityLocked: called recursively, r=" + r + ", reason=" + reason);
2985         mDoingSetFocusedActivity = true;
2986
2987         final ActivityRecord last = mFocusedActivity;
2988         mFocusedActivity = r;
2989         if (r.task.isApplicationTask()) {
2990             if (mCurAppTimeTracker != r.appTimeTracker) {
2991                 // We are switching app tracking.  Complete the current one.
2992                 if (mCurAppTimeTracker != null) {
2993                     mCurAppTimeTracker.stop();
2994                     mHandler.obtainMessage(
2995                             REPORT_TIME_TRACKER_MSG, mCurAppTimeTracker).sendToTarget();
2996                     mStackSupervisor.clearOtherAppTimeTrackers(r.appTimeTracker);
2997                     mCurAppTimeTracker = null;
2998                 }
2999                 if (r.appTimeTracker != null) {
3000                     mCurAppTimeTracker = r.appTimeTracker;
3001                     startTimeTrackingFocusedActivityLocked();
3002                 }
3003             } else {
3004                 startTimeTrackingFocusedActivityLocked();
3005             }
3006         } else {
3007             r.appTimeTracker = null;
3008         }
3009         // TODO: VI Maybe r.task.voiceInteractor || r.voiceInteractor != null
3010         // TODO: Probably not, because we don't want to resume voice on switching
3011         // back to this activity
3012         if (r.task.voiceInteractor != null) {
3013             startRunningVoiceLocked(r.task.voiceSession, r.info.applicationInfo.uid);
3014         } else {
3015             finishRunningVoiceLocked();
3016             IVoiceInteractionSession session;
3017             if (last != null && ((session = last.task.voiceSession) != null
3018                     || (session = last.voiceSession) != null)) {
3019                 // We had been in a voice interaction session, but now focused has
3020                 // move to something different.  Just finish the session, we can't
3021                 // return to it and retain the proper state and synchronization with
3022                 // the voice interaction service.
3023                 finishVoiceTask(session);
3024             }
3025         }
3026         if (mStackSupervisor.moveActivityStackToFront(r, reason + " setFocusedActivity")) {
3027             mWindowManager.setFocusedApp(r.appToken, true);
3028         }
3029         applyUpdateLockStateLocked(r);
3030         applyUpdateVrModeLocked(r);
3031         if (mFocusedActivity.userId != mLastFocusedUserId) {
3032             mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3033             mHandler.obtainMessage(
3034                     FOREGROUND_PROFILE_CHANGED_MSG, mFocusedActivity.userId, 0).sendToTarget();
3035             mLastFocusedUserId = mFocusedActivity.userId;
3036         }
3037
3038         // Log a warning if the focused app is changed during the process. This could
3039         // indicate a problem of the focus setting logic!
3040         if (mFocusedActivity != r) Slog.w(TAG,
3041                 "setFocusedActivityLocked: r=" + r + " but focused to " + mFocusedActivity);
3042         mDoingSetFocusedActivity = wasDoingSetFocusedActivity;
3043
3044         EventLogTags.writeAmFocusedActivity(
3045                 mFocusedActivity == null ? -1 : mFocusedActivity.userId,
3046                 mFocusedActivity == null ? "NULL" : mFocusedActivity.shortComponentName,
3047                 reason);
3048         return true;
3049     }
3050
3051     final void resetFocusedActivityIfNeededLocked(ActivityRecord goingAway) {
3052         if (mFocusedActivity != goingAway) {
3053             return;
3054         }
3055
3056         final ActivityStack focusedStack = mStackSupervisor.getFocusedStack();
3057         if (focusedStack != null) {
3058             final ActivityRecord top = focusedStack.topActivity();
3059             if (top != null && top.userId != mLastFocusedUserId) {
3060                 mHandler.removeMessages(FOREGROUND_PROFILE_CHANGED_MSG);
3061                 mHandler.sendMessage(
3062                         mHandler.obtainMessage(FOREGROUND_PROFILE_CHANGED_MSG, top.userId, 0));
3063                 mLastFocusedUserId = top.userId;
3064             }
3065         }
3066
3067         // Try to move focus to another activity if possible.
3068         if (setFocusedActivityLocked(
3069                 focusedStack.topRunningActivityLocked(), "resetFocusedActivityIfNeeded")) {
3070             return;
3071         }
3072
3073         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "resetFocusedActivityIfNeeded: Setting focus to NULL "
3074                 + "prev mFocusedActivity=" + mFocusedActivity + " goingAway=" + goingAway);
3075         mFocusedActivity = null;
3076         EventLogTags.writeAmFocusedActivity(-1, "NULL", "resetFocusedActivityIfNeeded");
3077     }
3078
3079     @Override
3080     public void setFocusedStack(int stackId) {
3081         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedStack()");
3082         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedStack: stackId=" + stackId);
3083         final long callingId = Binder.clearCallingIdentity();
3084         try {
3085             synchronized (this) {
3086                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
3087                 if (stack == null) {
3088                     return;
3089                 }
3090                 final ActivityRecord r = stack.topRunningActivityLocked();
3091                 if (setFocusedActivityLocked(r, "setFocusedStack")) {
3092                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3093                 }
3094             }
3095         } finally {
3096             Binder.restoreCallingIdentity(callingId);
3097         }
3098     }
3099
3100     @Override
3101     public void setFocusedTask(int taskId) {
3102         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "setFocusedTask()");
3103         if (DEBUG_FOCUS) Slog.d(TAG_FOCUS, "setFocusedTask: taskId=" + taskId);
3104         final long callingId = Binder.clearCallingIdentity();
3105         try {
3106             synchronized (this) {
3107                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
3108                 if (task == null) {
3109                     return;
3110                 }
3111                 if (mUserController.shouldConfirmCredentials(task.userId)) {
3112                     mActivityStarter.showConfirmDeviceCredential(task.userId);
3113                     if (task.stack != null && task.stack.mStackId == FREEFORM_WORKSPACE_STACK_ID) {
3114                         mStackSupervisor.moveTaskToStackLocked(task.taskId,
3115                                 FULLSCREEN_WORKSPACE_STACK_ID, !ON_TOP, !FORCE_FOCUS,
3116                                 "setFocusedTask", ANIMATE);
3117                     }
3118                     return;
3119                 }
3120                 final ActivityRecord r = task.topRunningActivityLocked();
3121                 if (setFocusedActivityLocked(r, "setFocusedTask")) {
3122                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
3123                 }
3124             }
3125         } finally {
3126             Binder.restoreCallingIdentity(callingId);
3127         }
3128     }
3129
3130     /** Sets the task stack listener that gets callbacks when a task stack changes. */
3131     @Override
3132     public void registerTaskStackListener(ITaskStackListener listener) throws RemoteException {
3133         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "registerTaskStackListener()");
3134         synchronized (this) {
3135             if (listener != null) {
3136                 mTaskStackListeners.register(listener);
3137             }
3138         }
3139     }
3140
3141     @Override
3142     public void notifyActivityDrawn(IBinder token) {
3143         if (DEBUG_VISIBILITY) Slog.d(TAG_VISIBILITY, "notifyActivityDrawn: token=" + token);
3144         synchronized (this) {
3145             ActivityRecord r = mStackSupervisor.isInAnyStackLocked(token);
3146             if (r != null) {
3147                 r.task.stack.notifyActivityDrawnLocked(r);
3148             }
3149         }
3150     }
3151
3152     final void applyUpdateLockStateLocked(ActivityRecord r) {
3153         // Modifications to the UpdateLock state are done on our handler, outside
3154         // the activity manager's locks.  The new state is determined based on the
3155         // state *now* of the relevant activity record.  The object is passed to
3156         // the handler solely for logging detail, not to be consulted/modified.
3157         final boolean nextState = r != null && r.immersive;
3158         mHandler.sendMessage(
3159                 mHandler.obtainMessage(IMMERSIVE_MODE_LOCK_MSG, (nextState) ? 1 : 0, 0, r));
3160     }
3161
3162     final void applyUpdateVrModeLocked(ActivityRecord r) {
3163         mHandler.sendMessage(
3164                 mHandler.obtainMessage(VR_MODE_CHANGE_MSG, 0, 0, r));
3165     }
3166
3167     private void applyVrModeIfNeededLocked(ActivityRecord r, boolean enable) {
3168         mHandler.sendMessage(
3169                 mHandler.obtainMessage(VR_MODE_APPLY_IF_NEEDED_MSG, enable ? 1 : 0, 0, r));
3170     }
3171
3172     private void applyVrMode(boolean enabled, ComponentName packageName, int userId,
3173             ComponentName callingPackage, boolean immediate) {
3174         VrManagerInternal vrService =
3175                 LocalServices.getService(VrManagerInternal.class);
3176         if (immediate) {
3177             vrService.setVrModeImmediate(enabled, packageName, userId, callingPackage);
3178         } else {
3179             vrService.setVrMode(enabled, packageName, userId, callingPackage);
3180         }
3181     }
3182
3183     final void showAskCompatModeDialogLocked(ActivityRecord r) {
3184         Message msg = Message.obtain();
3185         msg.what = SHOW_COMPAT_MODE_DIALOG_UI_MSG;
3186         msg.obj = r.task.askedCompatMode ? null : r;
3187         mUiHandler.sendMessage(msg);
3188     }
3189
3190     final void showUnsupportedZoomDialogIfNeededLocked(ActivityRecord r) {
3191         if (mConfiguration.densityDpi != DisplayMetrics.DENSITY_DEVICE_STABLE
3192                 && r.appInfo.requiresSmallestWidthDp > mConfiguration.smallestScreenWidthDp) {
3193             final Message msg = Message.obtain();
3194             msg.what = SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG;
3195             msg.obj = r;
3196             mUiHandler.sendMessage(msg);
3197         }
3198     }
3199
3200     private int updateLruProcessInternalLocked(ProcessRecord app, long now, int index,
3201             String what, Object obj, ProcessRecord srcApp) {
3202         app.lastActivityTime = now;
3203
3204         if (app.activities.size() > 0) {
3205             // Don't want to touch dependent processes that are hosting activities.
3206             return index;
3207         }
3208
3209         int lrui = mLruProcesses.lastIndexOf(app);
3210         if (lrui < 0) {
3211             Slog.wtf(TAG, "Adding dependent process " + app + " not on LRU list: "
3212                     + what + " " + obj + " from " + srcApp);
3213             return index;
3214         }
3215
3216         if (lrui >= index) {
3217             // Don't want to cause this to move dependent processes *back* in the
3218             // list as if they were less frequently used.
3219             return index;
3220         }
3221
3222         if (lrui >= mLruProcessActivityStart) {
3223             // Don't want to touch dependent processes that are hosting activities.
3224             return index;
3225         }
3226
3227         mLruProcesses.remove(lrui);
3228         if (index > 0) {
3229             index--;
3230         }
3231         if (DEBUG_LRU) Slog.d(TAG_LRU, "Moving dep from " + lrui + " to " + index
3232                 + " in LRU list: " + app);
3233         mLruProcesses.add(index, app);
3234         return index;
3235     }
3236
3237     static void killProcessGroup(int uid, int pid) {
3238         if (sKillHandler != null) {
3239             sKillHandler.sendMessage(
3240                     sKillHandler.obtainMessage(KillHandler.KILL_PROCESS_GROUP_MSG, uid, pid));
3241         } else {
3242             Slog.w(TAG, "Asked to kill process group before system bringup!");
3243             Process.killProcessGroup(uid, pid);
3244         }
3245     }
3246
3247     final void removeLruProcessLocked(ProcessRecord app) {
3248         int lrui = mLruProcesses.lastIndexOf(app);
3249         if (lrui >= 0) {
3250             if (!app.killed) {
3251                 Slog.wtfStack(TAG, "Removing process that hasn't been killed: " + app);
3252                 Process.killProcessQuiet(app.pid);
3253                 killProcessGroup(app.uid, app.pid);
3254             }
3255             if (lrui <= mLruProcessActivityStart) {
3256                 mLruProcessActivityStart--;
3257             }
3258             if (lrui <= mLruProcessServiceStart) {
3259                 mLruProcessServiceStart--;
3260             }
3261             mLruProcesses.remove(lrui);
3262         }
3263     }
3264
3265     final void updateLruProcessLocked(ProcessRecord app, boolean activityChange,
3266             ProcessRecord client) {
3267         final boolean hasActivity = app.activities.size() > 0 || app.hasClientActivities
3268                 || app.treatLikeActivity;
3269         final boolean hasService = false; // not impl yet. app.services.size() > 0;
3270         if (!activityChange && hasActivity) {
3271             // The process has activities, so we are only allowing activity-based adjustments
3272             // to move it.  It should be kept in the front of the list with other
3273             // processes that have activities, and we don't want those to change their
3274             // order except due to activity operations.
3275             return;
3276         }
3277
3278         mLruSeq++;
3279         final long now = SystemClock.uptimeMillis();
3280         app.lastActivityTime = now;
3281
3282         // First a quick reject: if the app is already at the position we will
3283         // put it, then there is nothing to do.
3284         if (hasActivity) {
3285             final int N = mLruProcesses.size();
3286             if (N > 0 && mLruProcesses.get(N-1) == app) {
3287                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top activity: " + app);
3288                 return;
3289             }
3290         } else {
3291             if (mLruProcessServiceStart > 0
3292                     && mLruProcesses.get(mLruProcessServiceStart-1) == app) {
3293                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, already top other: " + app);
3294                 return;
3295             }
3296         }
3297
3298         int lrui = mLruProcesses.lastIndexOf(app);
3299
3300         if (app.persistent && lrui >= 0) {
3301             // We don't care about the position of persistent processes, as long as
3302             // they are in the list.
3303             if (DEBUG_LRU) Slog.d(TAG_LRU, "Not moving, persistent: " + app);
3304             return;
3305         }
3306
3307         /* In progress: compute new position first, so we can avoid doing work
3308            if the process is not actually going to move.  Not yet working.
3309         int addIndex;
3310         int nextIndex;
3311         boolean inActivity = false, inService = false;
3312         if (hasActivity) {
3313             // Process has activities, put it at the very tipsy-top.
3314             addIndex = mLruProcesses.size();
3315             nextIndex = mLruProcessServiceStart;
3316             inActivity = true;
3317         } else if (hasService) {
3318             // Process has services, put it at the top of the service list.
3319             addIndex = mLruProcessActivityStart;
3320             nextIndex = mLruProcessServiceStart;
3321             inActivity = true;
3322             inService = true;
3323         } else  {
3324             // Process not otherwise of interest, it goes to the top of the non-service area.
3325             addIndex = mLruProcessServiceStart;
3326             if (client != null) {
3327                 int clientIndex = mLruProcesses.lastIndexOf(client);
3328                 if (clientIndex < 0) Slog.d(TAG, "Unknown client " + client + " when updating "
3329                         + app);
3330                 if (clientIndex >= 0 && addIndex > clientIndex) {
3331                     addIndex = clientIndex;
3332                 }
3333             }
3334             nextIndex = addIndex > 0 ? addIndex-1 : addIndex;
3335         }
3336
3337         Slog.d(TAG, "Update LRU at " + lrui + " to " + addIndex + " (act="
3338                 + mLruProcessActivityStart + "): " + app);
3339         */
3340
3341         if (lrui >= 0) {
3342             if (lrui < mLruProcessActivityStart) {
3343                 mLruProcessActivityStart--;
3344             }
3345             if (lrui < mLruProcessServiceStart) {
3346                 mLruProcessServiceStart--;
3347             }
3348             /*
3349             if (addIndex > lrui) {
3350                 addIndex--;
3351             }
3352             if (nextIndex > lrui) {
3353                 nextIndex--;
3354             }
3355             */
3356             mLruProcesses.remove(lrui);
3357         }
3358
3359         /*
3360         mLruProcesses.add(addIndex, app);
3361         if (inActivity) {
3362             mLruProcessActivityStart++;
3363         }
3364         if (inService) {
3365             mLruProcessActivityStart++;
3366         }
3367         */
3368
3369         int nextIndex;
3370         if (hasActivity) {
3371             final int N = mLruProcesses.size();
3372             if (app.activities.size() == 0 && mLruProcessActivityStart < (N - 1)) {
3373                 // Process doesn't have activities, but has clients with
3374                 // activities...  move it up, but one below the top (the top
3375                 // should always have a real activity).
3376                 if (DEBUG_LRU) Slog.d(TAG_LRU,
3377                         "Adding to second-top of LRU activity list: " + app);
3378                 mLruProcesses.add(N - 1, app);
3379                 // To keep it from spamming the LRU list (by making a bunch of clients),
3380                 // we will push down any other entries owned by the app.
3381                 final int uid = app.info.uid;
3382                 for (int i = N - 2; i > mLruProcessActivityStart; i--) {
3383                     ProcessRecord subProc = mLruProcesses.get(i);
3384                     if (subProc.info.uid == uid) {
3385                         // We want to push this one down the list.  If the process after
3386                         // it is for the same uid, however, don't do so, because we don't
3387                         // want them internally to be re-ordered.
3388                         if (mLruProcesses.get(i - 1).info.uid != uid) {
3389                             if (DEBUG_LRU) Slog.d(TAG_LRU,
3390                                     "Pushing uid " + uid + " swapping at " + i + ": "
3391                                     + mLruProcesses.get(i) + " : " + mLruProcesses.get(i - 1));
3392                             ProcessRecord tmp = mLruProcesses.get(i);
3393                             mLruProcesses.set(i, mLruProcesses.get(i - 1));
3394                             mLruProcesses.set(i - 1, tmp);
3395                             i--;
3396                         }
3397                     } else {
3398                         // A gap, we can stop here.
3399                         break;
3400                     }
3401                 }
3402             } else {
3403                 // Process has activities, put it at the very tipsy-top.
3404                 if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU activity list: " + app);
3405                 mLruProcesses.add(app);
3406             }
3407             nextIndex = mLruProcessServiceStart;
3408         } else if (hasService) {
3409             // Process has services, put it at the top of the service list.
3410             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding to top of LRU service list: " + app);
3411             mLruProcesses.add(mLruProcessActivityStart, app);
3412             nextIndex = mLruProcessServiceStart;
3413             mLruProcessActivityStart++;
3414         } else  {
3415             // Process not otherwise of interest, it goes to the top of the non-service area.
3416             int index = mLruProcessServiceStart;
3417             if (client != null) {
3418                 // If there is a client, don't allow the process to be moved up higher
3419                 // in the list than that client.
3420                 int clientIndex = mLruProcesses.lastIndexOf(client);
3421                 if (DEBUG_LRU && clientIndex < 0) Slog.d(TAG_LRU, "Unknown client " + client
3422                         + " when updating " + app);
3423                 if (clientIndex <= lrui) {
3424                     // Don't allow the client index restriction to push it down farther in the
3425                     // list than it already is.
3426                     clientIndex = lrui;
3427                 }
3428                 if (clientIndex >= 0 && index > clientIndex) {
3429                     index = clientIndex;
3430                 }
3431             }
3432             if (DEBUG_LRU) Slog.d(TAG_LRU, "Adding at " + index + " of LRU list: " + app);
3433             mLruProcesses.add(index, app);
3434             nextIndex = index-1;
3435             mLruProcessActivityStart++;
3436             mLruProcessServiceStart++;
3437         }
3438
3439         // If the app is currently using a content provider or service,
3440         // bump those processes as well.
3441         for (int j=app.connections.size()-1; j>=0; j--) {
3442             ConnectionRecord cr = app.connections.valueAt(j);
3443             if (cr.binding != null && !cr.serviceDead && cr.binding.service != null
3444                     && cr.binding.service.app != null
3445                     && cr.binding.service.app.lruSeq != mLruSeq
3446                     && !cr.binding.service.app.persistent) {
3447                 nextIndex = updateLruProcessInternalLocked(cr.binding.service.app, now, nextIndex,
3448                         "service connection", cr, app);
3449             }
3450         }
3451         for (int j=app.conProviders.size()-1; j>=0; j--) {
3452             ContentProviderRecord cpr = app.conProviders.get(j).provider;
3453             if (cpr.proc != null && cpr.proc.lruSeq != mLruSeq && !cpr.proc.persistent) {
3454                 nextIndex = updateLruProcessInternalLocked(cpr.proc, now, nextIndex,
3455                         "provider reference", cpr, app);
3456             }
3457         }
3458     }
3459
3460     final ProcessRecord getProcessRecordLocked(String processName, int uid, boolean keepIfLarge) {
3461         if (uid == Process.SYSTEM_UID) {
3462             // The system gets to run in any process.  If there are multiple
3463             // processes with the same uid, just pick the first (this
3464             // should never happen).
3465             SparseArray<ProcessRecord> procs = mProcessNames.getMap().get(processName);
3466             if (procs == null) return null;
3467             final int procCount = procs.size();
3468             for (int i = 0; i < procCount; i++) {
3469                 final int procUid = procs.keyAt(i);
3470                 if (UserHandle.isApp(procUid) || !UserHandle.isSameUser(procUid, uid)) {
3471                     // Don't use an app process or different user process for system component.
3472                     continue;
3473                 }
3474                 return procs.valueAt(i);
3475             }
3476         }
3477         ProcessRecord proc = mProcessNames.get(processName, uid);
3478         if (false && proc != null && !keepIfLarge
3479                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY
3480                 && proc.lastCachedPss >= 4000) {
3481             // Turn this condition on to cause killing to happen regularly, for testing.
3482             if (proc.baseProcessTracker != null) {
3483                 proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3484             }
3485             proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3486         } else if (proc != null && !keepIfLarge
3487                 && mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
3488                 && proc.setProcState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
3489             if (DEBUG_PSS) Slog.d(TAG_PSS, "May not keep " + proc + ": pss=" + proc.lastCachedPss);
3490             if (proc.lastCachedPss >= mProcessList.getCachedRestoreThresholdKb()) {
3491                 if (proc.baseProcessTracker != null) {
3492                     proc.baseProcessTracker.reportCachedKill(proc.pkgList, proc.lastCachedPss);
3493                 }
3494                 proc.kill(Long.toString(proc.lastCachedPss) + "k from cached", true);
3495             }
3496         }
3497         return proc;
3498     }
3499
3500     void notifyPackageUse(String packageName, int reason) {
3501         IPackageManager pm = AppGlobals.getPackageManager();
3502         try {
3503             pm.notifyPackageUse(packageName, reason);
3504         } catch (RemoteException e) {
3505         }
3506     }
3507
3508     boolean isNextTransitionForward() {
3509         int transit = mWindowManager.getPendingAppTransition();
3510         return transit == TRANSIT_ACTIVITY_OPEN
3511                 || transit == TRANSIT_TASK_OPEN
3512                 || transit == TRANSIT_TASK_TO_FRONT;
3513     }
3514
3515     int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
3516             String processName, String abiOverride, int uid, Runnable crashHandler) {
3517         synchronized(this) {
3518             ApplicationInfo info = new ApplicationInfo();
3519             // In general the ApplicationInfo.uid isn't neccesarily equal to ProcessRecord.uid.
3520             // For isolated processes, the former contains the parent's uid and the latter the
3521             // actual uid of the isolated process.
3522             // In the special case introduced by this method (which is, starting an isolated
3523             // process directly from the SystemServer without an actual parent app process) the
3524             // closest thing to a parent's uid is SYSTEM_UID.
3525             // The only important thing here is to keep AI.uid != PR.uid, in order to trigger
3526             // the |isolated| logic in the ProcessRecord constructor.
3527             info.uid = Process.SYSTEM_UID;
3528             info.processName = processName;
3529             info.className = entryPoint;
3530             info.packageName = "android";
3531             ProcessRecord proc = startProcessLocked(processName, info /* info */,
3532                     false /* knownToBeDead */, 0 /* intentFlags */, ""  /* hostingType */,
3533                     null /* hostingName */, true /* allowWhileBooting */, true /* isolated */,
3534                     uid, true /* keepIfLarge */, abiOverride, entryPoint, entryPointArgs,
3535                     crashHandler);
3536             return proc != null ? proc.pid : 0;
3537         }
3538     }
3539
3540     final ProcessRecord startProcessLocked(String processName,
3541             ApplicationInfo info, boolean knownToBeDead, int intentFlags,
3542             String hostingType, ComponentName hostingName, boolean allowWhileBooting,
3543             boolean isolated, boolean keepIfLarge) {
3544         return startProcessLocked(processName, info, knownToBeDead, intentFlags, hostingType,
3545                 hostingName, allowWhileBooting, isolated, 0 /* isolatedUid */, keepIfLarge,
3546                 null /* ABI override */, null /* entryPoint */, null /* entryPointArgs */,
3547                 null /* crashHandler */);
3548     }
3549
3550     final ProcessRecord startProcessLocked(String processName, ApplicationInfo info,
3551             boolean knownToBeDead, int intentFlags, String hostingType, ComponentName hostingName,
3552             boolean allowWhileBooting, boolean isolated, int isolatedUid, boolean keepIfLarge,
3553             String abiOverride, String entryPoint, String[] entryPointArgs, Runnable crashHandler) {
3554         long startTime = SystemClock.elapsedRealtime();
3555         ProcessRecord app;
3556         if (!isolated) {
3557             app = getProcessRecordLocked(processName, info.uid, keepIfLarge);
3558             checkTime(startTime, "startProcess: after getProcessRecord");
3559
3560             if ((intentFlags & Intent.FLAG_FROM_BACKGROUND) != 0) {
3561                 // If we are in the background, then check to see if this process
3562                 // is bad.  If so, we will just silently fail.
3563                 if (mAppErrors.isBadProcessLocked(info)) {
3564                     if (DEBUG_PROCESSES) Slog.v(TAG, "Bad process: " + info.uid
3565                             + "/" + info.processName);
3566                     return null;
3567                 }
3568             } else {
3569                 // When the user is explicitly starting a process, then clear its
3570                 // crash count so that we won't make it bad until they see at
3571                 // least one crash dialog again, and make the process good again
3572                 // if it had been bad.
3573                 if (DEBUG_PROCESSES) Slog.v(TAG, "Clearing bad process: " + info.uid
3574                         + "/" + info.processName);
3575                 mAppErrors.resetProcessCrashTimeLocked(info);
3576                 if (mAppErrors.isBadProcessLocked(info)) {
3577                     EventLog.writeEvent(EventLogTags.AM_PROC_GOOD,
3578                             UserHandle.getUserId(info.uid), info.uid,
3579                             info.processName);
3580                     mAppErrors.clearBadProcessLocked(info);
3581                     if (app != null) {
3582                         app.bad = false;
3583                     }
3584                 }
3585             }
3586         } else {
3587             // If this is an isolated process, it can't re-use an existing process.
3588             app = null;
3589         }
3590
3591         // app launch boost for big.little configurations
3592         // use cpusets to migrate freshly launched tasks to big cores
3593         nativeMigrateToBoost();
3594         mIsBoosted = true;
3595         mBoostStartTime = SystemClock.uptimeMillis();
3596         Message msg = mHandler.obtainMessage(APP_BOOST_DEACTIVATE_MSG);
3597         mHandler.sendMessageDelayed(msg, APP_BOOST_MESSAGE_DELAY);
3598
3599         // We don't have to do anything more if:
3600         // (1) There is an existing application record; and
3601         // (2) The caller doesn't think it is dead, OR there is no thread
3602         //     object attached to it so we know it couldn't have crashed; and
3603         // (3) There is a pid assigned to it, so it is either starting or
3604         //     already running.
3605         if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "startProcess: name=" + processName
3606                 + " app=" + app + " knownToBeDead=" + knownToBeDead
3607                 + " thread=" + (app != null ? app.thread : null)
3608                 + " pid=" + (app != null ? app.pid : -1));
3609         if (app != null && app.pid > 0) {
3610             if ((!knownToBeDead && !app.killed) || app.thread == null) {
3611                 // We already have the app running, or are waiting for it to
3612                 // come up (we have a pid but not yet its thread), so keep it.
3613                 if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "App already running: " + app);
3614                 // If this is a new package in the process, add the package to the list
3615                 app.addPackage(info.packageName, info.versionCode, mProcessStats);
3616                 checkTime(startTime, "startProcess: done, added package to proc");
3617                 return app;
3618             }
3619
3620             // An application record is attached to a previous process,
3621             // clean it up now.
3622             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_PROCESSES, "App died: " + app);
3623             checkTime(startTime, "startProcess: bad proc running, killing");
3624             killProcessGroup(app.uid, app.pid);
3625             handleAppDiedLocked(app, true, true);
3626             checkTime(startTime, "startProcess: done killing old proc");
3627         }
3628
3629         String hostingNameStr = hostingName != null
3630                 ? hostingName.flattenToShortString() : null;
3631
3632         if (app == null) {
3633             checkTime(startTime, "startProcess: creating new process record");
3634             app = newProcessRecordLocked(info, processName, isolated, isolatedUid);
3635             if (app == null) {
3636                 Slog.w(TAG, "Failed making new process record for "
3637                         + processName + "/" + info.uid + " isolated=" + isolated);
3638                 return null;
3639             }
3640             app.crashHandler = crashHandler;
3641             checkTime(startTime, "startProcess: done creating new process record");
3642         } else {
3643             // If this is a new package in the process, add the package to the list
3644             app.addPackage(info.packageName, info.versionCode, mProcessStats);
3645             checkTime(startTime, "startProcess: added package to existing proc");
3646         }
3647
3648         // If the system is not ready yet, then hold off on starting this
3649         // process until it is.
3650         if (!mProcessesReady
3651                 && !isAllowedWhileBooting(info)
3652                 && !allowWhileBooting) {
3653             if (!mProcessesOnHold.contains(app)) {
3654                 mProcessesOnHold.add(app);
3655             }
3656             if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES,
3657                     "System not ready, putting on hold: " + app);
3658             checkTime(startTime, "startProcess: returning with proc on hold");
3659             return app;
3660         }
3661
3662         checkTime(startTime, "startProcess: stepping in to startProcess");
3663         startProcessLocked(
3664                 app, hostingType, hostingNameStr, abiOverride, entryPoint, entryPointArgs);
3665         checkTime(startTime, "startProcess: done starting proc!");
3666         return (app.pid != 0) ? app : null;
3667     }
3668
3669     boolean isAllowedWhileBooting(ApplicationInfo ai) {
3670         return (ai.flags&ApplicationInfo.FLAG_PERSISTENT) != 0;
3671     }
3672
3673     private final void startProcessLocked(ProcessRecord app,
3674             String hostingType, String hostingNameStr) {
3675         startProcessLocked(app, hostingType, hostingNameStr, null /* abiOverride */,
3676                 null /* entryPoint */, null /* entryPointArgs */);
3677     }
3678
3679     private final void startProcessLocked(ProcessRecord app, String hostingType,
3680             String hostingNameStr, String abiOverride, String entryPoint, String[] entryPointArgs) {
3681         long startTime = SystemClock.elapsedRealtime();
3682         if (app.pid > 0 && app.pid != MY_PID) {
3683             checkTime(startTime, "startProcess: removing from pids map");
3684             synchronized (mPidsSelfLocked) {
3685                 mPidsSelfLocked.remove(app.pid);
3686                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
3687             }
3688             checkTime(startTime, "startProcess: done removing from pids map");
3689             app.setPid(0);
3690         }
3691
3692         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
3693                 "startProcessLocked removing on hold: " + app);
3694         mProcessesOnHold.remove(app);
3695
3696         checkTime(startTime, "startProcess: starting to update cpu stats");
3697         updateCpuStats();
3698         checkTime(startTime, "startProcess: done updating cpu stats");
3699
3700         try {
3701             try {
3702                 final int userId = UserHandle.getUserId(app.uid);
3703                 AppGlobals.getPackageManager().checkPackageStartable(app.info.packageName, userId);
3704             } catch (RemoteException e) {
3705                 throw e.rethrowAsRuntimeException();
3706             }
3707
3708             int uid = app.uid;
3709             int[] gids = null;
3710             int mountExternal = Zygote.MOUNT_EXTERNAL_NONE;
3711             if (!app.isolated) {
3712                 int[] permGids = null;
3713                 try {
3714                     checkTime(startTime, "startProcess: getting gids from package manager");
3715                     final IPackageManager pm = AppGlobals.getPackageManager();
3716                     permGids = pm.getPackageGids(app.info.packageName,
3717                             MATCH_DEBUG_TRIAGED_MISSING, app.userId);
3718                     MountServiceInternal mountServiceInternal = LocalServices.getService(
3719                             MountServiceInternal.class);
3720                     mountExternal = mountServiceInternal.getExternalStorageMountMode(uid,
3721                             app.info.packageName);
3722                 } catch (RemoteException e) {
3723                     throw e.rethrowAsRuntimeException();
3724                 }
3725
3726                 /*
3727                  * Add shared application and profile GIDs so applications can share some
3728                  * resources like shared libraries and access user-wide resources
3729                  */
3730                 if (ArrayUtils.isEmpty(permGids)) {
3731                     gids = new int[2];
3732                 } else {
3733                     gids = new int[permGids.length + 2];
3734                     System.arraycopy(permGids, 0, gids, 2, permGids.length);
3735                 }
3736                 gids[0] = UserHandle.getSharedAppGid(UserHandle.getAppId(uid));
3737                 gids[1] = UserHandle.getUserGid(UserHandle.getUserId(uid));
3738             }
3739             checkTime(startTime, "startProcess: building args");
3740             if (mFactoryTest != FactoryTest.FACTORY_TEST_OFF) {
3741                 if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3742                         && mTopComponent != null
3743                         && app.processName.equals(mTopComponent.getPackageName())) {
3744                     uid = 0;
3745                 }
3746                 if (mFactoryTest == FactoryTest.FACTORY_TEST_HIGH_LEVEL
3747                         && (app.info.flags&ApplicationInfo.FLAG_FACTORY_TEST) != 0) {
3748                     uid = 0;
3749                 }
3750             }
3751             int debugFlags = 0;
3752             if ((app.info.flags & ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
3753                 debugFlags |= Zygote.DEBUG_ENABLE_DEBUGGER;
3754                 // Also turn on CheckJNI for debuggable apps. It's quite
3755                 // awkward to turn on otherwise.
3756                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3757             }
3758             // Run the app in safe mode if its manifest requests so or the
3759             // system is booted in safe mode.
3760             if ((app.info.flags & ApplicationInfo.FLAG_VM_SAFE_MODE) != 0 ||
3761                 mSafeMode == true) {
3762                 debugFlags |= Zygote.DEBUG_ENABLE_SAFEMODE;
3763             }
3764             if ("1".equals(SystemProperties.get("debug.checkjni"))) {
3765                 debugFlags |= Zygote.DEBUG_ENABLE_CHECKJNI;
3766             }
3767             String genDebugInfoProperty = SystemProperties.get("debug.generate-debug-info");
3768             if ("true".equals(genDebugInfoProperty)) {
3769                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO;
3770             }
3771             if ("1".equals(SystemProperties.get("debug.jni.logging"))) {
3772                 debugFlags |= Zygote.DEBUG_ENABLE_JNI_LOGGING;
3773             }
3774             if ("1".equals(SystemProperties.get("debug.assert"))) {
3775                 debugFlags |= Zygote.DEBUG_ENABLE_ASSERT;
3776             }
3777             if (mNativeDebuggingApp != null && mNativeDebuggingApp.equals(app.processName)) {
3778                 // Enable all debug flags required by the native debugger.
3779                 debugFlags |= Zygote.DEBUG_ALWAYS_JIT;          // Don't interpret anything
3780                 debugFlags |= Zygote.DEBUG_GENERATE_DEBUG_INFO; // Generate debug info
3781                 debugFlags |= Zygote.DEBUG_NATIVE_DEBUGGABLE;   // Disbale optimizations
3782                 mNativeDebuggingApp = null;
3783             }
3784
3785             String requiredAbi = (abiOverride != null) ? abiOverride : app.info.primaryCpuAbi;
3786             if (requiredAbi == null) {
3787                 requiredAbi = Build.SUPPORTED_ABIS[0];
3788             }
3789
3790             String instructionSet = null;
3791             if (app.info.primaryCpuAbi != null) {
3792                 instructionSet = VMRuntime.getInstructionSet(app.info.primaryCpuAbi);
3793             }
3794
3795             app.gids = gids;
3796             app.requiredAbi = requiredAbi;
3797             app.instructionSet = instructionSet;
3798
3799             // Start the process.  It will either succeed and return a result containing
3800             // the PID of the new process, or else throw a RuntimeException.
3801             boolean isActivityProcess = (entryPoint == null);
3802             if (entryPoint == null) entryPoint = "android.app.ActivityThread";
3803             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "Start proc: " +
3804                     app.processName);
3805             checkTime(startTime, "startProcess: asking zygote to start proc");
3806             Process.ProcessStartResult startResult = Process.start(entryPoint,
3807                     app.processName, uid, uid, gids, debugFlags, mountExternal,
3808                     app.info.targetSdkVersion, app.info.seinfo, requiredAbi, instructionSet,
3809                     app.info.dataDir, entryPointArgs);
3810             checkTime(startTime, "startProcess: returned from zygote!");
3811             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
3812
3813             mBatteryStatsService.noteProcessStart(app.processName, app.info.uid);
3814             checkTime(startTime, "startProcess: done updating battery stats");
3815
3816             EventLog.writeEvent(EventLogTags.AM_PROC_START,
3817                     UserHandle.getUserId(uid), startResult.pid, uid,
3818                     app.processName, hostingType,
3819                     hostingNameStr != null ? hostingNameStr : "");
3820
3821             try {
3822                 AppGlobals.getPackageManager().logAppProcessStartIfNeeded(app.processName, app.uid,
3823                         app.info.seinfo, app.info.sourceDir, startResult.pid);
3824             } catch (RemoteException ex) {
3825                 // Ignore
3826             }
3827
3828             if (app.persistent) {
3829                 Watchdog.getInstance().processStarted(app.processName, startResult.pid);
3830             }
3831
3832             checkTime(startTime, "startProcess: building log message");
3833             StringBuilder buf = mStringBuilder;
3834             buf.setLength(0);
3835             buf.append("Start proc ");
3836             buf.append(startResult.pid);
3837             buf.append(':');
3838             buf.append(app.processName);
3839             buf.append('/');
3840             UserHandle.formatUid(buf, uid);
3841             if (!isActivityProcess) {
3842                 buf.append(" [");
3843                 buf.append(entryPoint);
3844                 buf.append("]");
3845             }
3846             buf.append(" for ");
3847             buf.append(hostingType);
3848             if (hostingNameStr != null) {
3849                 buf.append(" ");
3850                 buf.append(hostingNameStr);
3851             }
3852             Slog.i(TAG, buf.toString());
3853             app.setPid(startResult.pid);
3854             app.usingWrapper = startResult.usingWrapper;
3855             app.removed = false;
3856             app.killed = false;
3857             app.killedByAm = false;
3858             checkTime(startTime, "startProcess: starting to update pids map");
3859             ProcessRecord oldApp;
3860             synchronized (mPidsSelfLocked) {
3861                 oldApp = mPidsSelfLocked.get(startResult.pid);
3862             }
3863             // If there is already an app occupying that pid that hasn't been cleaned up
3864             if (oldApp != null && !app.isolated) {
3865                 // Clean up anything relating to this pid first
3866                 Slog.w(TAG, "Reusing pid " + startResult.pid
3867                         + " while app is still mapped to it");
3868                 cleanUpApplicationRecordLocked(oldApp, false, false, -1,
3869                         true /*replacingPid*/);
3870             }
3871             synchronized (mPidsSelfLocked) {
3872                 this.mPidsSelfLocked.put(startResult.pid, app);
3873                 if (isActivityProcess) {
3874                     Message msg = mHandler.obtainMessage(PROC_START_TIMEOUT_MSG);
3875                     msg.obj = app;
3876                     mHandler.sendMessageDelayed(msg, startResult.usingWrapper
3877                             ? PROC_START_TIMEOUT_WITH_WRAPPER : PROC_START_TIMEOUT);
3878                 }
3879             }
3880             checkTime(startTime, "startProcess: done updating pids map");
3881         } catch (RuntimeException e) {
3882             Slog.e(TAG, "Failure starting process " + app.processName, e);
3883
3884             // Something went very wrong while trying to start this process; one
3885             // common case is when the package is frozen due to an active
3886             // upgrade. To recover, clean up any active bookkeeping related to
3887             // starting this process. (We already invoked this method once when
3888             // the package was initially frozen through KILL_APPLICATION_MSG, so
3889             // it doesn't hurt to use it again.)
3890             forceStopPackageLocked(app.info.packageName, UserHandle.getAppId(app.uid), false,
3891                     false, true, false, false, UserHandle.getUserId(app.userId), "start failure");
3892         }
3893     }
3894
3895     void updateUsageStats(ActivityRecord component, boolean resumed) {
3896         if (DEBUG_SWITCH) Slog.d(TAG_SWITCH,
3897                 "updateUsageStats: comp=" + component + "res=" + resumed);
3898         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
3899         if (resumed) {
3900             if (mUsageStatsService != null) {
3901                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3902                         UsageEvents.Event.MOVE_TO_FOREGROUND);
3903             }
3904             synchronized (stats) {
3905                 stats.noteActivityResumedLocked(component.app.uid);
3906             }
3907         } else {
3908             if (mUsageStatsService != null) {
3909                 mUsageStatsService.reportEvent(component.realActivity, component.userId,
3910                         UsageEvents.Event.MOVE_TO_BACKGROUND);
3911             }
3912             synchronized (stats) {
3913                 stats.noteActivityPausedLocked(component.app.uid);
3914             }
3915         }
3916     }
3917
3918     Intent getHomeIntent() {
3919         Intent intent = new Intent(mTopAction, mTopData != null ? Uri.parse(mTopData) : null);
3920         intent.setComponent(mTopComponent);
3921         intent.addFlags(Intent.FLAG_DEBUG_TRIAGED_MISSING);
3922         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
3923             intent.addCategory(Intent.CATEGORY_HOME);
3924         }
3925         return intent;
3926     }
3927
3928     boolean startHomeActivityLocked(int userId, String reason) {
3929         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL
3930                 && mTopAction == null) {
3931             // We are running in factory test mode, but unable to find
3932             // the factory test app, so just sit around displaying the
3933             // error message and don't try to start anything.
3934             return false;
3935         }
3936         Intent intent = getHomeIntent();
3937         ActivityInfo aInfo = resolveActivityInfo(intent, STOCK_PM_FLAGS, userId);
3938         if (aInfo != null) {
3939             intent.setComponent(new ComponentName(aInfo.applicationInfo.packageName, aInfo.name));
3940             // Don't do this if the home app is currently being
3941             // instrumented.
3942             aInfo = new ActivityInfo(aInfo);
3943             aInfo.applicationInfo = getAppInfoForUser(aInfo.applicationInfo, userId);
3944             ProcessRecord app = getProcessRecordLocked(aInfo.processName,
3945                     aInfo.applicationInfo.uid, true);
3946             if (app == null || app.instrumentationClass == null) {
3947                 intent.setFlags(intent.getFlags() | Intent.FLAG_ACTIVITY_NEW_TASK);
3948                 mActivityStarter.startHomeActivityLocked(intent, aInfo, reason);
3949             }
3950         } else {
3951             Slog.wtf(TAG, "No home screen found for " + intent, new Throwable());
3952         }
3953
3954         return true;
3955     }
3956
3957     private ActivityInfo resolveActivityInfo(Intent intent, int flags, int userId) {
3958         ActivityInfo ai = null;
3959         ComponentName comp = intent.getComponent();
3960         try {
3961             if (comp != null) {
3962                 // Factory test.
3963                 ai = AppGlobals.getPackageManager().getActivityInfo(comp, flags, userId);
3964             } else {
3965                 ResolveInfo info = AppGlobals.getPackageManager().resolveIntent(
3966                         intent,
3967                         intent.resolveTypeIfNeeded(mContext.getContentResolver()),
3968                         flags, userId);
3969
3970                 if (info != null) {
3971                     ai = info.activityInfo;
3972                 }
3973             }
3974         } catch (RemoteException e) {
3975             // ignore
3976         }
3977
3978         return ai;
3979     }
3980
3981     /**
3982      * Starts the "new version setup screen" if appropriate.
3983      */
3984     void startSetupActivityLocked() {
3985         // Only do this once per boot.
3986         if (mCheckedForSetup) {
3987             return;
3988         }
3989
3990         // We will show this screen if the current one is a different
3991         // version than the last one shown, and we are not running in
3992         // low-level factory test mode.
3993         final ContentResolver resolver = mContext.getContentResolver();
3994         if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL &&
3995                 Settings.Global.getInt(resolver,
3996                         Settings.Global.DEVICE_PROVISIONED, 0) != 0) {
3997             mCheckedForSetup = true;
3998
3999             // See if we should be showing the platform update setup UI.
4000             final Intent intent = new Intent(Intent.ACTION_UPGRADE_SETUP);
4001             final List<ResolveInfo> ris = mContext.getPackageManager().queryIntentActivities(intent,
4002                     PackageManager.MATCH_SYSTEM_ONLY | PackageManager.GET_META_DATA);
4003             if (!ris.isEmpty()) {
4004                 final ResolveInfo ri = ris.get(0);
4005                 String vers = ri.activityInfo.metaData != null
4006                         ? ri.activityInfo.metaData.getString(Intent.METADATA_SETUP_VERSION)
4007                         : null;
4008                 if (vers == null && ri.activityInfo.applicationInfo.metaData != null) {
4009                     vers = ri.activityInfo.applicationInfo.metaData.getString(
4010                             Intent.METADATA_SETUP_VERSION);
4011                 }
4012                 String lastVers = Settings.Secure.getString(
4013                         resolver, Settings.Secure.LAST_SETUP_SHOWN);
4014                 if (vers != null && !vers.equals(lastVers)) {
4015                     intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK);
4016                     intent.setComponent(new ComponentName(
4017                             ri.activityInfo.packageName, ri.activityInfo.name));
4018                     mActivityStarter.startActivityLocked(null, intent, null /*ephemeralIntent*/,
4019                             null, ri.activityInfo, null /*rInfo*/, null, null, null, null, 0, 0, 0,
4020                             null, 0, 0, 0, null, false, false, null, null, null);
4021                 }
4022             }
4023         }
4024     }
4025
4026     CompatibilityInfo compatibilityInfoForPackageLocked(ApplicationInfo ai) {
4027         return mCompatModePackages.compatibilityInfoForPackageLocked(ai);
4028     }
4029
4030     void enforceNotIsolatedCaller(String caller) {
4031         if (UserHandle.isIsolated(Binder.getCallingUid())) {
4032             throw new SecurityException("Isolated process not allowed to call " + caller);
4033         }
4034     }
4035
4036     void enforceShellRestriction(String restriction, int userHandle) {
4037         if (Binder.getCallingUid() == Process.SHELL_UID) {
4038             if (userHandle < 0 || mUserController.hasUserRestriction(restriction, userHandle)) {
4039                 throw new SecurityException("Shell does not have permission to access user "
4040                         + userHandle);
4041             }
4042         }
4043     }
4044
4045     @Override
4046     public int getFrontActivityScreenCompatMode() {
4047         enforceNotIsolatedCaller("getFrontActivityScreenCompatMode");
4048         synchronized (this) {
4049             return mCompatModePackages.getFrontActivityScreenCompatModeLocked();
4050         }
4051     }
4052
4053     @Override
4054     public void setFrontActivityScreenCompatMode(int mode) {
4055         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4056                 "setFrontActivityScreenCompatMode");
4057         synchronized (this) {
4058             mCompatModePackages.setFrontActivityScreenCompatModeLocked(mode);
4059         }
4060     }
4061
4062     @Override
4063     public int getPackageScreenCompatMode(String packageName) {
4064         enforceNotIsolatedCaller("getPackageScreenCompatMode");
4065         synchronized (this) {
4066             return mCompatModePackages.getPackageScreenCompatModeLocked(packageName);
4067         }
4068     }
4069
4070     @Override
4071     public void setPackageScreenCompatMode(String packageName, int mode) {
4072         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4073                 "setPackageScreenCompatMode");
4074         synchronized (this) {
4075             mCompatModePackages.setPackageScreenCompatModeLocked(packageName, mode);
4076         }
4077     }
4078
4079     @Override
4080     public boolean getPackageAskScreenCompat(String packageName) {
4081         enforceNotIsolatedCaller("getPackageAskScreenCompat");
4082         synchronized (this) {
4083             return mCompatModePackages.getPackageAskCompatModeLocked(packageName);
4084         }
4085     }
4086
4087     @Override
4088     public void setPackageAskScreenCompat(String packageName, boolean ask) {
4089         enforceCallingPermission(android.Manifest.permission.SET_SCREEN_COMPATIBILITY,
4090                 "setPackageAskScreenCompat");
4091         synchronized (this) {
4092             mCompatModePackages.setPackageAskCompatModeLocked(packageName, ask);
4093         }
4094     }
4095
4096     private boolean hasUsageStatsPermission(String callingPackage) {
4097         final int mode = mAppOpsService.checkOperation(AppOpsManager.OP_GET_USAGE_STATS,
4098                 Binder.getCallingUid(), callingPackage);
4099         if (mode == AppOpsManager.MODE_DEFAULT) {
4100             return checkCallingPermission(Manifest.permission.PACKAGE_USAGE_STATS)
4101                     == PackageManager.PERMISSION_GRANTED;
4102         }
4103         return mode == AppOpsManager.MODE_ALLOWED;
4104     }
4105
4106     @Override
4107     public int getPackageProcessState(String packageName, String callingPackage) {
4108         if (!hasUsageStatsPermission(callingPackage)) {
4109             enforceCallingPermission(android.Manifest.permission.GET_PACKAGE_IMPORTANCE,
4110                     "getPackageProcessState");
4111         }
4112
4113         int procState = ActivityManager.PROCESS_STATE_NONEXISTENT;
4114         synchronized (this) {
4115             for (int i=mLruProcesses.size()-1; i>=0; i--) {
4116                 final ProcessRecord proc = mLruProcesses.get(i);
4117                 if (procState == ActivityManager.PROCESS_STATE_NONEXISTENT
4118                         || procState > proc.setProcState) {
4119                     boolean found = false;
4120                     for (int j=proc.pkgList.size()-1; j>=0 && !found; j--) {
4121                         if (proc.pkgList.keyAt(j).equals(packageName)) {
4122                             procState = proc.setProcState;
4123                             found = true;
4124                         }
4125                     }
4126                     if (proc.pkgDeps != null && !found) {
4127                         for (int j=proc.pkgDeps.size()-1; j>=0; j--) {
4128                             if (proc.pkgDeps.valueAt(j).equals(packageName)) {
4129                                 procState = proc.setProcState;
4130                                 break;
4131                             }
4132                         }
4133                     }
4134                 }
4135             }
4136         }
4137         return procState;
4138     }
4139
4140     @Override
4141     public boolean setProcessMemoryTrimLevel(String process, int userId, int level) {
4142         synchronized (this) {
4143             final ProcessRecord app = findProcessLocked(process, userId, "setProcessMemoryTrimLevel");
4144             if (app == null) {
4145                 return false;
4146             }
4147             if (app.trimMemoryLevel < level && app.thread != null &&
4148                     (level < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN ||
4149                             app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND)) {
4150                 try {
4151                     app.thread.scheduleTrimMemory(level);
4152                     app.trimMemoryLevel = level;
4153                     return true;
4154                 } catch (RemoteException e) {
4155                     // Fallthrough to failure case.
4156                 }
4157             }
4158         }
4159         return false;
4160     }
4161
4162     private void dispatchProcessesChanged() {
4163         int N;
4164         synchronized (this) {
4165             N = mPendingProcessChanges.size();
4166             if (mActiveProcessChanges.length < N) {
4167                 mActiveProcessChanges = new ProcessChangeItem[N];
4168             }
4169             mPendingProcessChanges.toArray(mActiveProcessChanges);
4170             mPendingProcessChanges.clear();
4171             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4172                     "*** Delivering " + N + " process changes");
4173         }
4174
4175         int i = mProcessObservers.beginBroadcast();
4176         while (i > 0) {
4177             i--;
4178             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4179             if (observer != null) {
4180                 try {
4181                     for (int j=0; j<N; j++) {
4182                         ProcessChangeItem item = mActiveProcessChanges[j];
4183                         if ((item.changes&ProcessChangeItem.CHANGE_ACTIVITIES) != 0) {
4184                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4185                                     "ACTIVITIES CHANGED pid=" + item.pid + " uid="
4186                                     + item.uid + ": " + item.foregroundActivities);
4187                             observer.onForegroundActivitiesChanged(item.pid, item.uid,
4188                                     item.foregroundActivities);
4189                         }
4190                         if ((item.changes&ProcessChangeItem.CHANGE_PROCESS_STATE) != 0) {
4191                             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
4192                                     "PROCSTATE CHANGED pid=" + item.pid + " uid=" + item.uid
4193                                     + ": " + item.processState);
4194                             observer.onProcessStateChanged(item.pid, item.uid, item.processState);
4195                         }
4196                     }
4197                 } catch (RemoteException e) {
4198                 }
4199             }
4200         }
4201         mProcessObservers.finishBroadcast();
4202
4203         synchronized (this) {
4204             for (int j=0; j<N; j++) {
4205                 mAvailProcessChanges.add(mActiveProcessChanges[j]);
4206             }
4207         }
4208     }
4209
4210     private void dispatchProcessDied(int pid, int uid) {
4211         int i = mProcessObservers.beginBroadcast();
4212         while (i > 0) {
4213             i--;
4214             final IProcessObserver observer = mProcessObservers.getBroadcastItem(i);
4215             if (observer != null) {
4216                 try {
4217                     observer.onProcessDied(pid, uid);
4218                 } catch (RemoteException e) {
4219                 }
4220             }
4221         }
4222         mProcessObservers.finishBroadcast();
4223     }
4224
4225     private void dispatchUidsChanged() {
4226         int N;
4227         synchronized (this) {
4228             N = mPendingUidChanges.size();
4229             if (mActiveUidChanges.length < N) {
4230                 mActiveUidChanges = new UidRecord.ChangeItem[N];
4231             }
4232             for (int i=0; i<N; i++) {
4233                 final UidRecord.ChangeItem change = mPendingUidChanges.get(i);
4234                 mActiveUidChanges[i] = change;
4235                 if (change.uidRecord != null) {
4236                     change.uidRecord.pendingChange = null;
4237                     change.uidRecord = null;
4238                 }
4239             }
4240             mPendingUidChanges.clear();
4241             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4242                     "*** Delivering " + N + " uid changes");
4243         }
4244
4245         if (mLocalPowerManager != null) {
4246             for (int j=0; j<N; j++) {
4247                 UidRecord.ChangeItem item = mActiveUidChanges[j];
4248                 if (item.change == UidRecord.CHANGE_GONE
4249                         || item.change == UidRecord.CHANGE_GONE_IDLE) {
4250                     mLocalPowerManager.uidGone(item.uid);
4251                 } else {
4252                     mLocalPowerManager.updateUidProcState(item.uid, item.processState);
4253                 }
4254             }
4255         }
4256
4257         int i = mUidObservers.beginBroadcast();
4258         while (i > 0) {
4259             i--;
4260             final IUidObserver observer = mUidObservers.getBroadcastItem(i);
4261             final int which = (Integer)mUidObservers.getBroadcastCookie(i);
4262             if (observer != null) {
4263                 try {
4264                     for (int j=0; j<N; j++) {
4265                         UidRecord.ChangeItem item = mActiveUidChanges[j];
4266                         final int change = item.change;
4267                         UidRecord validateUid = null;
4268                         if (VALIDATE_UID_STATES && i == 0) {
4269                             validateUid = mValidateUids.get(item.uid);
4270                             if (validateUid == null && change != UidRecord.CHANGE_GONE
4271                                     && change != UidRecord.CHANGE_GONE_IDLE) {
4272                                 validateUid = new UidRecord(item.uid);
4273                                 mValidateUids.put(item.uid, validateUid);
4274                             }
4275                         }
4276                         if (change == UidRecord.CHANGE_IDLE
4277                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4278                             if ((which & ActivityManager.UID_OBSERVER_IDLE) != 0) {
4279                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4280                                         "UID idle uid=" + item.uid);
4281                                 observer.onUidIdle(item.uid);
4282                             }
4283                             if (VALIDATE_UID_STATES && i == 0) {
4284                                 if (validateUid != null) {
4285                                     validateUid.idle = true;
4286                                 }
4287                             }
4288                         } else if (change == UidRecord.CHANGE_ACTIVE) {
4289                             if ((which & ActivityManager.UID_OBSERVER_ACTIVE) != 0) {
4290                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4291                                         "UID active uid=" + item.uid);
4292                                 observer.onUidActive(item.uid);
4293                             }
4294                             if (VALIDATE_UID_STATES && i == 0) {
4295                                 validateUid.idle = false;
4296                             }
4297                         }
4298                         if (change == UidRecord.CHANGE_GONE
4299                                 || change == UidRecord.CHANGE_GONE_IDLE) {
4300                             if ((which & ActivityManager.UID_OBSERVER_GONE) != 0) {
4301                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4302                                         "UID gone uid=" + item.uid);
4303                                 observer.onUidGone(item.uid);
4304                             }
4305                             if (VALIDATE_UID_STATES && i == 0) {
4306                                 if (validateUid != null) {
4307                                     mValidateUids.remove(item.uid);
4308                                 }
4309                             }
4310                         } else {
4311                             if ((which & ActivityManager.UID_OBSERVER_PROCSTATE) != 0) {
4312                                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
4313                                         "UID CHANGED uid=" + item.uid
4314                                                 + ": " + item.processState);
4315                                 observer.onUidStateChanged(item.uid, item.processState);
4316                             }
4317                             if (VALIDATE_UID_STATES && i == 0) {
4318                                 validateUid.curProcState = validateUid.setProcState
4319                                         = item.processState;
4320                             }
4321                         }
4322                     }
4323                 } catch (RemoteException e) {
4324                 }
4325             }
4326         }
4327         mUidObservers.finishBroadcast();
4328
4329         synchronized (this) {
4330             for (int j=0; j<N; j++) {
4331                 mAvailUidChanges.add(mActiveUidChanges[j]);
4332             }
4333         }
4334     }
4335
4336     @Override
4337     public final int startActivity(IApplicationThread caller, String callingPackage,
4338             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4339             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions) {
4340         return startActivityAsUser(caller, callingPackage, intent, resolvedType, resultTo,
4341                 resultWho, requestCode, startFlags, profilerInfo, bOptions,
4342                 UserHandle.getCallingUserId());
4343     }
4344
4345     final int startActivity(Intent intent, ActivityStackSupervisor.ActivityContainer container) {
4346         enforceNotIsolatedCaller("ActivityContainer.startActivity");
4347         final int userId = mUserController.handleIncomingUser(Binder.getCallingPid(),
4348                 Binder.getCallingUid(), mStackSupervisor.mCurrentUser, false,
4349                 ActivityManagerService.ALLOW_FULL_ONLY, "ActivityContainer", null);
4350
4351         // TODO: Switch to user app stacks here.
4352         String mimeType = intent.getType();
4353         final Uri data = intent.getData();
4354         if (mimeType == null && data != null && "content".equals(data.getScheme())) {
4355             mimeType = getProviderMimeType(data, userId);
4356         }
4357         container.checkEmbeddedAllowedInner(userId, intent, mimeType);
4358
4359         intent.addFlags(FORCE_NEW_TASK_FLAGS);
4360         return mActivityStarter.startActivityMayWait(null, -1, null, intent, mimeType, null, null, null,
4361                 null, 0, 0, null, null, null, null, false, userId, container, null);
4362     }
4363
4364     @Override
4365     public final int startActivityAsUser(IApplicationThread caller, String callingPackage,
4366             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4367             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4368         enforceNotIsolatedCaller("startActivity");
4369         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4370                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4371         // TODO: Switch to user app stacks here.
4372         return mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4373                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4374                 profilerInfo, null, null, bOptions, false, userId, null, null);
4375     }
4376
4377     @Override
4378     public final int startActivityAsCaller(IApplicationThread caller, String callingPackage,
4379             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4380             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, boolean ignoreTargetSecurity,
4381             int userId) {
4382
4383         // This is very dangerous -- it allows you to perform a start activity (including
4384         // permission grants) as any app that may launch one of your own activities.  So
4385         // we will only allow this to be done from activities that are part of the core framework,
4386         // and then only when they are running as the system.
4387         final ActivityRecord sourceRecord;
4388         final int targetUid;
4389         final String targetPackage;
4390         synchronized (this) {
4391             if (resultTo == null) {
4392                 throw new SecurityException("Must be called from an activity");
4393             }
4394             sourceRecord = mStackSupervisor.isInAnyStackLocked(resultTo);
4395             if (sourceRecord == null) {
4396                 throw new SecurityException("Called with bad activity token: " + resultTo);
4397             }
4398             if (!sourceRecord.info.packageName.equals("android")) {
4399                 throw new SecurityException(
4400                         "Must be called from an activity that is declared in the android package");
4401             }
4402             if (sourceRecord.app == null) {
4403                 throw new SecurityException("Called without a process attached to activity");
4404             }
4405             if (UserHandle.getAppId(sourceRecord.app.uid) != Process.SYSTEM_UID) {
4406                 // This is still okay, as long as this activity is running under the
4407                 // uid of the original calling activity.
4408                 if (sourceRecord.app.uid != sourceRecord.launchedFromUid) {
4409                     throw new SecurityException(
4410                             "Calling activity in uid " + sourceRecord.app.uid
4411                                     + " must be system uid or original calling uid "
4412                                     + sourceRecord.launchedFromUid);
4413                 }
4414             }
4415             if (ignoreTargetSecurity) {
4416                 if (intent.getComponent() == null) {
4417                     throw new SecurityException(
4418                             "Component must be specified with ignoreTargetSecurity");
4419                 }
4420                 if (intent.getSelector() != null) {
4421                     throw new SecurityException(
4422                             "Selector not allowed with ignoreTargetSecurity");
4423                 }
4424             }
4425             targetUid = sourceRecord.launchedFromUid;
4426             targetPackage = sourceRecord.launchedFromPackage;
4427         }
4428
4429         if (userId == UserHandle.USER_NULL) {
4430             userId = UserHandle.getUserId(sourceRecord.app.uid);
4431         }
4432
4433         // TODO: Switch to user app stacks here.
4434         try {
4435             int ret = mActivityStarter.startActivityMayWait(null, targetUid, targetPackage, intent,
4436                     resolvedType, null, null, resultTo, resultWho, requestCode, startFlags, null,
4437                     null, null, bOptions, ignoreTargetSecurity, userId, null, null);
4438             return ret;
4439         } catch (SecurityException e) {
4440             // XXX need to figure out how to propagate to original app.
4441             // A SecurityException here is generally actually a fault of the original
4442             // calling activity (such as a fairly granting permissions), so propagate it
4443             // back to them.
4444             /*
4445             StringBuilder msg = new StringBuilder();
4446             msg.append("While launching");
4447             msg.append(intent.toString());
4448             msg.append(": ");
4449             msg.append(e.getMessage());
4450             */
4451             throw e;
4452         }
4453     }
4454
4455     @Override
4456     public final WaitResult startActivityAndWait(IApplicationThread caller, String callingPackage,
4457             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4458             int startFlags, ProfilerInfo profilerInfo, Bundle bOptions, int userId) {
4459         enforceNotIsolatedCaller("startActivityAndWait");
4460         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4461                 userId, false, ALLOW_FULL_ONLY, "startActivityAndWait", null);
4462         WaitResult res = new WaitResult();
4463         // TODO: Switch to user app stacks here.
4464         mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent, resolvedType,
4465                 null, null, resultTo, resultWho, requestCode, startFlags, profilerInfo, res, null,
4466                 bOptions, false, userId, null, null);
4467         return res;
4468     }
4469
4470     @Override
4471     public final int startActivityWithConfig(IApplicationThread caller, String callingPackage,
4472             Intent intent, String resolvedType, IBinder resultTo, String resultWho, int requestCode,
4473             int startFlags, Configuration config, Bundle bOptions, int userId) {
4474         enforceNotIsolatedCaller("startActivityWithConfig");
4475         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4476                 userId, false, ALLOW_FULL_ONLY, "startActivityWithConfig", null);
4477         // TODO: Switch to user app stacks here.
4478         int ret = mActivityStarter.startActivityMayWait(caller, -1, callingPackage, intent,
4479                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4480                 null, null, config, bOptions, false, userId, null, null);
4481         return ret;
4482     }
4483
4484     @Override
4485     public int startActivityIntentSender(IApplicationThread caller, IntentSender intent,
4486             Intent fillInIntent, String resolvedType, IBinder resultTo, String resultWho,
4487             int requestCode, int flagsMask, int flagsValues, Bundle bOptions)
4488             throws TransactionTooLargeException {
4489         enforceNotIsolatedCaller("startActivityIntentSender");
4490         // Refuse possible leaked file descriptors
4491         if (fillInIntent != null && fillInIntent.hasFileDescriptors()) {
4492             throw new IllegalArgumentException("File descriptors passed in Intent");
4493         }
4494
4495         IIntentSender sender = intent.getTarget();
4496         if (!(sender instanceof PendingIntentRecord)) {
4497             throw new IllegalArgumentException("Bad PendingIntent object");
4498         }
4499
4500         PendingIntentRecord pir = (PendingIntentRecord)sender;
4501
4502         synchronized (this) {
4503             // If this is coming from the currently resumed activity, it is
4504             // effectively saying that app switches are allowed at this point.
4505             final ActivityStack stack = getFocusedStack();
4506             if (stack.mResumedActivity != null &&
4507                     stack.mResumedActivity.info.applicationInfo.uid == Binder.getCallingUid()) {
4508                 mAppSwitchesAllowedTime = 0;
4509             }
4510         }
4511         int ret = pir.sendInner(0, fillInIntent, resolvedType, null, null,
4512                 resultTo, resultWho, requestCode, flagsMask, flagsValues, bOptions, null);
4513         return ret;
4514     }
4515
4516     @Override
4517     public int startVoiceActivity(String callingPackage, int callingPid, int callingUid,
4518             Intent intent, String resolvedType, IVoiceInteractionSession session,
4519             IVoiceInteractor interactor, int startFlags, ProfilerInfo profilerInfo,
4520             Bundle bOptions, int userId) {
4521         if (checkCallingPermission(Manifest.permission.BIND_VOICE_INTERACTION)
4522                 != PackageManager.PERMISSION_GRANTED) {
4523             String msg = "Permission Denial: startVoiceActivity() from pid="
4524                     + Binder.getCallingPid()
4525                     + ", uid=" + Binder.getCallingUid()
4526                     + " requires " + android.Manifest.permission.BIND_VOICE_INTERACTION;
4527             Slog.w(TAG, msg);
4528             throw new SecurityException(msg);
4529         }
4530         if (session == null || interactor == null) {
4531             throw new NullPointerException("null session or interactor");
4532         }
4533         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
4534                 ALLOW_FULL_ONLY, "startVoiceActivity", null);
4535         // TODO: Switch to user app stacks here.
4536         return mActivityStarter.startActivityMayWait(null, callingUid, callingPackage, intent,
4537                 resolvedType, session, interactor, null, null, 0, startFlags, profilerInfo, null,
4538                 null, bOptions, false, userId, null, null);
4539     }
4540
4541     @Override
4542     public void startLocalVoiceInteraction(IBinder callingActivity, Bundle options)
4543             throws RemoteException {
4544         Slog.i(TAG, "Activity tried to startVoiceInteraction");
4545         synchronized (this) {
4546             ActivityRecord activity = getFocusedStack().topActivity();
4547             if (ActivityRecord.forTokenLocked(callingActivity) != activity) {
4548                 throw new SecurityException("Only focused activity can call startVoiceInteraction");
4549             }
4550             if (mRunningVoice != null || activity.task.voiceSession != null
4551                     || activity.voiceSession != null) {
4552                 Slog.w(TAG, "Already in a voice interaction, cannot start new voice interaction");
4553                 return;
4554             }
4555             if (activity.pendingVoiceInteractionStart) {
4556                 Slog.w(TAG, "Pending start of voice interaction already.");
4557                 return;
4558             }
4559             activity.pendingVoiceInteractionStart = true;
4560         }
4561         LocalServices.getService(VoiceInteractionManagerInternal.class)
4562                 .startLocalVoiceInteraction(callingActivity, options);
4563     }
4564
4565     @Override
4566     public void stopLocalVoiceInteraction(IBinder callingActivity) throws RemoteException {
4567         LocalServices.getService(VoiceInteractionManagerInternal.class)
4568                 .stopLocalVoiceInteraction(callingActivity);
4569     }
4570
4571     @Override
4572     public boolean supportsLocalVoiceInteraction() throws RemoteException {
4573         return LocalServices.getService(VoiceInteractionManagerInternal.class)
4574                 .supportsLocalVoiceInteraction();
4575     }
4576
4577     void onLocalVoiceInteractionStartedLocked(IBinder activity,
4578             IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
4579         ActivityRecord activityToCallback = ActivityRecord.forTokenLocked(activity);
4580         if (activityToCallback == null) return;
4581         activityToCallback.setVoiceSessionLocked(voiceSession);
4582
4583         // Inform the activity
4584         try {
4585             activityToCallback.app.thread.scheduleLocalVoiceInteractionStarted(activity,
4586                     voiceInteractor);
4587             long token = Binder.clearCallingIdentity();
4588             try {
4589                 startRunningVoiceLocked(voiceSession, activityToCallback.appInfo.uid);
4590             } finally {
4591                 Binder.restoreCallingIdentity(token);
4592             }
4593             // TODO: VI Should we cache the activity so that it's easier to find later
4594             // rather than scan through all the stacks and activities?
4595         } catch (RemoteException re) {
4596             activityToCallback.clearVoiceSessionLocked();
4597             // TODO: VI Should this terminate the voice session?
4598         }
4599     }
4600
4601     @Override
4602     public void setVoiceKeepAwake(IVoiceInteractionSession session, boolean keepAwake) {
4603         synchronized (this) {
4604             if (mRunningVoice != null && mRunningVoice.asBinder() == session.asBinder()) {
4605                 if (keepAwake) {
4606                     mVoiceWakeLock.acquire();
4607                 } else {
4608                     mVoiceWakeLock.release();
4609                 }
4610             }
4611         }
4612     }
4613
4614     @Override
4615     public boolean startNextMatchingActivity(IBinder callingActivity,
4616             Intent intent, Bundle bOptions) {
4617         // Refuse possible leaked file descriptors
4618         if (intent != null && intent.hasFileDescriptors() == true) {
4619             throw new IllegalArgumentException("File descriptors passed in Intent");
4620         }
4621         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
4622
4623         synchronized (this) {
4624             final ActivityRecord r = ActivityRecord.isInStackLocked(callingActivity);
4625             if (r == null) {
4626                 ActivityOptions.abort(options);
4627                 return false;
4628             }
4629             if (r.app == null || r.app.thread == null) {
4630                 // The caller is not running...  d'oh!
4631                 ActivityOptions.abort(options);
4632                 return false;
4633             }
4634             intent = new Intent(intent);
4635             // The caller is not allowed to change the data.
4636             intent.setDataAndType(r.intent.getData(), r.intent.getType());
4637             // And we are resetting to find the next component...
4638             intent.setComponent(null);
4639
4640             final boolean debug = ((intent.getFlags() & Intent.FLAG_DEBUG_LOG_RESOLUTION) != 0);
4641
4642             ActivityInfo aInfo = null;
4643             try {
4644                 List<ResolveInfo> resolves =
4645                     AppGlobals.getPackageManager().queryIntentActivities(
4646                             intent, r.resolvedType,
4647                             PackageManager.MATCH_DEFAULT_ONLY | STOCK_PM_FLAGS,
4648                             UserHandle.getCallingUserId()).getList();
4649
4650                 // Look for the original activity in the list...
4651                 final int N = resolves != null ? resolves.size() : 0;
4652                 for (int i=0; i<N; i++) {
4653                     ResolveInfo rInfo = resolves.get(i);
4654                     if (rInfo.activityInfo.packageName.equals(r.packageName)
4655                             && rInfo.activityInfo.name.equals(r.info.name)) {
4656                         // We found the current one...  the next matching is
4657                         // after it.
4658                         i++;
4659                         if (i<N) {
4660                             aInfo = resolves.get(i).activityInfo;
4661                         }
4662                         if (debug) {
4663                             Slog.v(TAG, "Next matching activity: found current " + r.packageName
4664                                     + "/" + r.info.name);
4665                             Slog.v(TAG, "Next matching activity: next is " + ((aInfo == null)
4666                                     ? "null" : aInfo.packageName + "/" + aInfo.name));
4667                         }
4668                         break;
4669                     }
4670                 }
4671             } catch (RemoteException e) {
4672             }
4673
4674             if (aInfo == null) {
4675                 // Nobody who is next!
4676                 ActivityOptions.abort(options);
4677                 if (debug) Slog.d(TAG, "Next matching activity: nothing found");
4678                 return false;
4679             }
4680
4681             intent.setComponent(new ComponentName(
4682                     aInfo.applicationInfo.packageName, aInfo.name));
4683             intent.setFlags(intent.getFlags()&~(
4684                     Intent.FLAG_ACTIVITY_FORWARD_RESULT|
4685                     Intent.FLAG_ACTIVITY_CLEAR_TOP|
4686                     Intent.FLAG_ACTIVITY_MULTIPLE_TASK|
4687                     Intent.FLAG_ACTIVITY_NEW_TASK));
4688
4689             // Okay now we need to start the new activity, replacing the
4690             // currently running activity.  This is a little tricky because
4691             // we want to start the new one as if the current one is finished,
4692             // but not finish the current one first so that there is no flicker.
4693             // And thus...
4694             final boolean wasFinishing = r.finishing;
4695             r.finishing = true;
4696
4697             // Propagate reply information over to the new activity.
4698             final ActivityRecord resultTo = r.resultTo;
4699             final String resultWho = r.resultWho;
4700             final int requestCode = r.requestCode;
4701             r.resultTo = null;
4702             if (resultTo != null) {
4703                 resultTo.removeResultsLocked(r, resultWho, requestCode);
4704             }
4705
4706             final long origId = Binder.clearCallingIdentity();
4707             int res = mActivityStarter.startActivityLocked(r.app.thread, intent,
4708                     null /*ephemeralIntent*/, r.resolvedType, aInfo, null /*rInfo*/, null,
4709                     null, resultTo != null ? resultTo.appToken : null, resultWho, requestCode, -1,
4710                     r.launchedFromUid, r.launchedFromPackage, -1, r.launchedFromUid, 0, options,
4711                     false, false, null, null, null);
4712             Binder.restoreCallingIdentity(origId);
4713
4714             r.finishing = wasFinishing;
4715             if (res != ActivityManager.START_SUCCESS) {
4716                 return false;
4717             }
4718             return true;
4719         }
4720     }
4721
4722     @Override
4723     public final int startActivityFromRecents(int taskId, Bundle bOptions) {
4724         if (checkCallingPermission(START_TASKS_FROM_RECENTS) != PackageManager.PERMISSION_GRANTED) {
4725             String msg = "Permission Denial: startActivityFromRecents called without " +
4726                     START_TASKS_FROM_RECENTS;
4727             Slog.w(TAG, msg);
4728             throw new SecurityException(msg);
4729         }
4730         final long origId = Binder.clearCallingIdentity();
4731         try {
4732             synchronized (this) {
4733                 return mStackSupervisor.startActivityFromRecentsInner(taskId, bOptions);
4734             }
4735         } finally {
4736             Binder.restoreCallingIdentity(origId);
4737         }
4738     }
4739
4740     final int startActivityInPackage(int uid, String callingPackage,
4741             Intent intent, String resolvedType, IBinder resultTo,
4742             String resultWho, int requestCode, int startFlags, Bundle bOptions, int userId,
4743             IActivityContainer container, TaskRecord inTask) {
4744
4745         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4746                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4747
4748         // TODO: Switch to user app stacks here.
4749         int ret = mActivityStarter.startActivityMayWait(null, uid, callingPackage, intent,
4750                 resolvedType, null, null, resultTo, resultWho, requestCode, startFlags,
4751                 null, null, null, bOptions, false, userId, container, inTask);
4752         return ret;
4753     }
4754
4755     @Override
4756     public final int startActivities(IApplicationThread caller, String callingPackage,
4757             Intent[] intents, String[] resolvedTypes, IBinder resultTo, Bundle bOptions,
4758             int userId) {
4759         enforceNotIsolatedCaller("startActivities");
4760         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4761                 userId, false, ALLOW_FULL_ONLY, "startActivity", null);
4762         // TODO: Switch to user app stacks here.
4763         int ret = mActivityStarter.startActivities(caller, -1, callingPackage, intents,
4764                 resolvedTypes, resultTo, bOptions, userId);
4765         return ret;
4766     }
4767
4768     final int startActivitiesInPackage(int uid, String callingPackage,
4769             Intent[] intents, String[] resolvedTypes, IBinder resultTo,
4770             Bundle bOptions, int userId) {
4771
4772         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
4773                 userId, false, ALLOW_FULL_ONLY, "startActivityInPackage", null);
4774         // TODO: Switch to user app stacks here.
4775         int ret = mActivityStarter.startActivities(null, uid, callingPackage, intents, resolvedTypes,
4776                 resultTo, bOptions, userId);
4777         return ret;
4778     }
4779
4780     @Override
4781     public void reportActivityFullyDrawn(IBinder token) {
4782         synchronized (this) {
4783             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4784             if (r == null) {
4785                 return;
4786             }
4787             r.reportFullyDrawnLocked();
4788         }
4789     }
4790
4791     @Override
4792     public void setRequestedOrientation(IBinder token, int requestedOrientation) {
4793         synchronized (this) {
4794             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4795             if (r == null) {
4796                 return;
4797             }
4798             TaskRecord task = r.task;
4799             if (task != null && (!task.mFullscreen || !task.stack.mFullscreen)) {
4800                 // Fixed screen orientation isn't supported when activities aren't in full screen
4801                 // mode.
4802                 return;
4803             }
4804             final long origId = Binder.clearCallingIdentity();
4805             mWindowManager.setAppOrientation(r.appToken, requestedOrientation);
4806             Configuration config = mWindowManager.updateOrientationFromAppTokens(
4807                     mConfiguration, r.mayFreezeScreenLocked(r.app) ? r.appToken : null);
4808             if (config != null) {
4809                 r.frozenBeforeDestroy = true;
4810                 if (!updateConfigurationLocked(config, r, false)) {
4811                     mStackSupervisor.resumeFocusedStackTopActivityLocked();
4812                 }
4813             }
4814             Binder.restoreCallingIdentity(origId);
4815         }
4816     }
4817
4818     @Override
4819     public int getRequestedOrientation(IBinder token) {
4820         synchronized (this) {
4821             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4822             if (r == null) {
4823                 return ActivityInfo.SCREEN_ORIENTATION_UNSPECIFIED;
4824             }
4825             return mWindowManager.getAppOrientation(r.appToken);
4826         }
4827     }
4828
4829     /**
4830      * This is the internal entry point for handling Activity.finish().
4831      *
4832      * @param token The Binder token referencing the Activity we want to finish.
4833      * @param resultCode Result code, if any, from this Activity.
4834      * @param resultData Result data (Intent), if any, from this Activity.
4835      * @param finishTask Whether to finish the task associated with this Activity.
4836      *
4837      * @return Returns true if the activity successfully finished, or false if it is still running.
4838      */
4839     @Override
4840     public final boolean finishActivity(IBinder token, int resultCode, Intent resultData,
4841             int finishTask) {
4842         // Refuse possible leaked file descriptors
4843         if (resultData != null && resultData.hasFileDescriptors() == true) {
4844             throw new IllegalArgumentException("File descriptors passed in Intent");
4845         }
4846
4847         synchronized(this) {
4848             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4849             if (r == null) {
4850                 return true;
4851             }
4852             // Keep track of the root activity of the task before we finish it
4853             TaskRecord tr = r.task;
4854             ActivityRecord rootR = tr.getRootActivity();
4855             if (rootR == null) {
4856                 Slog.w(TAG, "Finishing task with all activities already finished");
4857             }
4858             // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps can
4859             // finish.
4860             if (tr.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV && rootR == r &&
4861                     mStackSupervisor.isLastLockedTask(tr)) {
4862                 Slog.i(TAG, "Not finishing task in lock task mode");
4863                 mStackSupervisor.showLockTaskToast();
4864                 return false;
4865             }
4866             if (mController != null) {
4867                 // Find the first activity that is not finishing.
4868                 ActivityRecord next = r.task.stack.topRunningActivityLocked(token, 0);
4869                 if (next != null) {
4870                     // ask watcher if this is allowed
4871                     boolean resumeOK = true;
4872                     try {
4873                         resumeOK = mController.activityResuming(next.packageName);
4874                     } catch (RemoteException e) {
4875                         mController = null;
4876                         Watchdog.getInstance().setActivityController(null);
4877                     }
4878
4879                     if (!resumeOK) {
4880                         Slog.i(TAG, "Not finishing activity because controller resumed");
4881                         return false;
4882                     }
4883                 }
4884             }
4885             final long origId = Binder.clearCallingIdentity();
4886             try {
4887                 boolean res;
4888                 final boolean finishWithRootActivity =
4889                         finishTask == Activity.FINISH_TASK_WITH_ROOT_ACTIVITY;
4890                 if (finishTask == Activity.FINISH_TASK_WITH_ACTIVITY
4891                         || (finishWithRootActivity && r == rootR)) {
4892                     // If requested, remove the task that is associated to this activity only if it
4893                     // was the root activity in the task. The result code and data is ignored
4894                     // because we don't support returning them across task boundaries. Also, to
4895                     // keep backwards compatibility we remove the task from recents when finishing
4896                     // task with root activity.
4897                     res = removeTaskByIdLocked(tr.taskId, false, finishWithRootActivity);
4898                     if (!res) {
4899                         Slog.i(TAG, "Removing task failed to finish activity");
4900                     }
4901                 } else {
4902                     res = tr.stack.requestFinishActivityLocked(token, resultCode,
4903                             resultData, "app-request", true);
4904                     if (!res) {
4905                         Slog.i(TAG, "Failed to finish by app-request");
4906                     }
4907                 }
4908                 return res;
4909             } finally {
4910                 Binder.restoreCallingIdentity(origId);
4911             }
4912         }
4913     }
4914
4915     @Override
4916     public final void finishHeavyWeightApp() {
4917         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4918                 != PackageManager.PERMISSION_GRANTED) {
4919             String msg = "Permission Denial: finishHeavyWeightApp() from pid="
4920                     + Binder.getCallingPid()
4921                     + ", uid=" + Binder.getCallingUid()
4922                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4923             Slog.w(TAG, msg);
4924             throw new SecurityException(msg);
4925         }
4926
4927         synchronized(this) {
4928             if (mHeavyWeightProcess == null) {
4929                 return;
4930             }
4931
4932             ArrayList<ActivityRecord> activities = new ArrayList<>(mHeavyWeightProcess.activities);
4933             for (int i = 0; i < activities.size(); i++) {
4934                 ActivityRecord r = activities.get(i);
4935                 if (!r.finishing && r.isInStackLocked()) {
4936                     r.task.stack.finishActivityLocked(r, Activity.RESULT_CANCELED,
4937                             null, "finish-heavy", true);
4938                 }
4939             }
4940
4941             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
4942                     mHeavyWeightProcess.userId, 0));
4943             mHeavyWeightProcess = null;
4944         }
4945     }
4946
4947     @Override
4948     public void crashApplication(int uid, int initialPid, String packageName,
4949             String message) {
4950         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
4951                 != PackageManager.PERMISSION_GRANTED) {
4952             String msg = "Permission Denial: crashApplication() from pid="
4953                     + Binder.getCallingPid()
4954                     + ", uid=" + Binder.getCallingUid()
4955                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
4956             Slog.w(TAG, msg);
4957             throw new SecurityException(msg);
4958         }
4959
4960         synchronized(this) {
4961             mAppErrors.scheduleAppCrashLocked(uid, initialPid, packageName, message);
4962         }
4963     }
4964
4965     @Override
4966     public final void finishSubActivity(IBinder token, String resultWho,
4967             int requestCode) {
4968         synchronized(this) {
4969             final long origId = Binder.clearCallingIdentity();
4970             ActivityRecord r = ActivityRecord.isInStackLocked(token);
4971             if (r != null) {
4972                 r.task.stack.finishSubActivityLocked(r, resultWho, requestCode);
4973             }
4974             Binder.restoreCallingIdentity(origId);
4975         }
4976     }
4977
4978     @Override
4979     public boolean finishActivityAffinity(IBinder token) {
4980         synchronized(this) {
4981             final long origId = Binder.clearCallingIdentity();
4982             try {
4983                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
4984                 if (r == null) {
4985                     return false;
4986                 }
4987
4988                 // Do not allow task to finish if last task in lockTask mode. Launchable priv-apps
4989                 // can finish.
4990                 final TaskRecord task = r.task;
4991                 if (task.mLockTaskAuth != LOCK_TASK_AUTH_LAUNCHABLE_PRIV &&
4992                         mStackSupervisor.isLastLockedTask(task) && task.getRootActivity() == r) {
4993                     mStackSupervisor.showLockTaskToast();
4994                     return false;
4995                 }
4996                 return task.stack.finishActivityAffinityLocked(r);
4997             } finally {
4998                 Binder.restoreCallingIdentity(origId);
4999             }
5000         }
5001     }
5002
5003     @Override
5004     public void finishVoiceTask(IVoiceInteractionSession session) {
5005         synchronized (this) {
5006             final long origId = Binder.clearCallingIdentity();
5007             try {
5008                 // TODO: VI Consider treating local voice interactions and voice tasks
5009                 // differently here
5010                 mStackSupervisor.finishVoiceTask(session);
5011             } finally {
5012                 Binder.restoreCallingIdentity(origId);
5013             }
5014         }
5015
5016     }
5017
5018     @Override
5019     public boolean releaseActivityInstance(IBinder token) {
5020         synchronized(this) {
5021             final long origId = Binder.clearCallingIdentity();
5022             try {
5023                 ActivityRecord r = ActivityRecord.isInStackLocked(token);
5024                 if (r == null) {
5025                     return false;
5026                 }
5027                 return r.task.stack.safelyDestroyActivityLocked(r, "app-req");
5028             } finally {
5029                 Binder.restoreCallingIdentity(origId);
5030             }
5031         }
5032     }
5033
5034     @Override
5035     public void releaseSomeActivities(IApplicationThread appInt) {
5036         synchronized(this) {
5037             final long origId = Binder.clearCallingIdentity();
5038             try {
5039                 ProcessRecord app = getRecordForAppLocked(appInt);
5040                 mStackSupervisor.releaseSomeActivitiesLocked(app, "low-mem");
5041             } finally {
5042                 Binder.restoreCallingIdentity(origId);
5043             }
5044         }
5045     }
5046
5047     @Override
5048     public boolean willActivityBeVisible(IBinder token) {
5049         synchronized(this) {
5050             ActivityStack stack = ActivityRecord.getStackLocked(token);
5051             if (stack != null) {
5052                 return stack.willActivityBeVisibleLocked(token);
5053             }
5054             return false;
5055         }
5056     }
5057
5058     @Override
5059     public void overridePendingTransition(IBinder token, String packageName,
5060             int enterAnim, int exitAnim) {
5061         synchronized(this) {
5062             ActivityRecord self = ActivityRecord.isInStackLocked(token);
5063             if (self == null) {
5064                 return;
5065             }
5066
5067             final long origId = Binder.clearCallingIdentity();
5068
5069             if (self.state == ActivityState.RESUMED
5070                     || self.state == ActivityState.PAUSING) {
5071                 mWindowManager.overridePendingAppTransition(packageName,
5072                         enterAnim, exitAnim, null);
5073             }
5074
5075             Binder.restoreCallingIdentity(origId);
5076         }
5077     }
5078
5079     /**
5080      * Main function for removing an existing process from the activity manager
5081      * as a result of that process going away.  Clears out all connections
5082      * to the process.
5083      */
5084     private final void handleAppDiedLocked(ProcessRecord app,
5085             boolean restarting, boolean allowRestart) {
5086         int pid = app.pid;
5087         boolean kept = cleanUpApplicationRecordLocked(app, restarting, allowRestart, -1,
5088                 false /*replacingPid*/);
5089         if (!kept && !restarting) {
5090             removeLruProcessLocked(app);
5091             if (pid > 0) {
5092                 ProcessList.remove(pid);
5093             }
5094         }
5095
5096         if (mProfileProc == app) {
5097             clearProfilerLocked();
5098         }
5099
5100         // Remove this application's activities from active lists.
5101         boolean hasVisibleActivities = mStackSupervisor.handleAppDiedLocked(app);
5102
5103         app.activities.clear();
5104
5105         if (app.instrumentationClass != null) {
5106             Slog.w(TAG, "Crash of app " + app.processName
5107                   + " running instrumentation " + app.instrumentationClass);
5108             Bundle info = new Bundle();
5109             info.putString("shortMsg", "Process crashed.");
5110             finishInstrumentationLocked(app, Activity.RESULT_CANCELED, info);
5111         }
5112
5113         if (!restarting && hasVisibleActivities
5114                 && !mStackSupervisor.resumeFocusedStackTopActivityLocked()) {
5115             // If there was nothing to resume, and we are not already restarting this process, but
5116             // there is a visible activity that is hosted by the process...  then make sure all
5117             // visible activities are running, taking care of restarting this process.
5118             mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
5119         }
5120     }
5121
5122     private final int getLRURecordIndexForAppLocked(IApplicationThread thread) {
5123         IBinder threadBinder = thread.asBinder();
5124         // Find the application record.
5125         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5126             ProcessRecord rec = mLruProcesses.get(i);
5127             if (rec.thread != null && rec.thread.asBinder() == threadBinder) {
5128                 return i;
5129             }
5130         }
5131         return -1;
5132     }
5133
5134     final ProcessRecord getRecordForAppLocked(
5135             IApplicationThread thread) {
5136         if (thread == null) {
5137             return null;
5138         }
5139
5140         int appIndex = getLRURecordIndexForAppLocked(thread);
5141         return appIndex >= 0 ? mLruProcesses.get(appIndex) : null;
5142     }
5143
5144     final void doLowMemReportIfNeededLocked(ProcessRecord dyingProc) {
5145         // If there are no longer any background processes running,
5146         // and the app that died was not running instrumentation,
5147         // then tell everyone we are now low on memory.
5148         boolean haveBg = false;
5149         for (int i=mLruProcesses.size()-1; i>=0; i--) {
5150             ProcessRecord rec = mLruProcesses.get(i);
5151             if (rec.thread != null
5152                     && rec.setProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
5153                 haveBg = true;
5154                 break;
5155             }
5156         }
5157
5158         if (!haveBg) {
5159             boolean doReport = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
5160             if (doReport) {
5161                 long now = SystemClock.uptimeMillis();
5162                 if (now < (mLastMemUsageReportTime+5*60*1000)) {
5163                     doReport = false;
5164                 } else {
5165                     mLastMemUsageReportTime = now;
5166                 }
5167             }
5168             final ArrayList<ProcessMemInfo> memInfos
5169                     = doReport ? new ArrayList<ProcessMemInfo>(mLruProcesses.size()) : null;
5170             EventLog.writeEvent(EventLogTags.AM_LOW_MEMORY, mLruProcesses.size());
5171             long now = SystemClock.uptimeMillis();
5172             for (int i=mLruProcesses.size()-1; i>=0; i--) {
5173                 ProcessRecord rec = mLruProcesses.get(i);
5174                 if (rec == dyingProc || rec.thread == null) {
5175                     continue;
5176                 }
5177                 if (doReport) {
5178                     memInfos.add(new ProcessMemInfo(rec.processName, rec.pid, rec.setAdj,
5179                             rec.setProcState, rec.adjType, rec.makeAdjReason()));
5180                 }
5181                 if ((rec.lastLowMemory+GC_MIN_INTERVAL) <= now) {
5182                     // The low memory report is overriding any current
5183                     // state for a GC request.  Make sure to do
5184                     // heavy/important/visible/foreground processes first.
5185                     if (rec.setAdj <= ProcessList.HEAVY_WEIGHT_APP_ADJ) {
5186                         rec.lastRequestedGc = 0;
5187                     } else {
5188                         rec.lastRequestedGc = rec.lastLowMemory;
5189                     }
5190                     rec.reportLowMemory = true;
5191                     rec.lastLowMemory = now;
5192                     mProcessesToGc.remove(rec);
5193                     addProcessToGcListLocked(rec);
5194                 }
5195             }
5196             if (doReport) {
5197                 Message msg = mHandler.obtainMessage(REPORT_MEM_USAGE_MSG, memInfos);
5198                 mHandler.sendMessage(msg);
5199             }
5200             scheduleAppGcsLocked();
5201         }
5202     }
5203
5204     final void appDiedLocked(ProcessRecord app) {
5205        appDiedLocked(app, app.pid, app.thread, false);
5206     }
5207
5208     final void appDiedLocked(ProcessRecord app, int pid, IApplicationThread thread,
5209             boolean fromBinderDied) {
5210         // First check if this ProcessRecord is actually active for the pid.
5211         synchronized (mPidsSelfLocked) {
5212             ProcessRecord curProc = mPidsSelfLocked.get(pid);
5213             if (curProc != app) {
5214                 Slog.w(TAG, "Spurious death for " + app + ", curProc for " + pid + ": " + curProc);
5215                 return;
5216             }
5217         }
5218
5219         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
5220         synchronized (stats) {
5221             stats.noteProcessDiedLocked(app.info.uid, pid);
5222         }
5223
5224         if (!app.killed) {
5225             if (!fromBinderDied) {
5226                 Process.killProcessQuiet(pid);
5227             }
5228             killProcessGroup(app.uid, pid);
5229             app.killed = true;
5230         }
5231
5232         // Clean up already done if the process has been re-started.
5233         if (app.pid == pid && app.thread != null &&
5234                 app.thread.asBinder() == thread.asBinder()) {
5235             boolean doLowMem = app.instrumentationClass == null;
5236             boolean doOomAdj = doLowMem;
5237             if (!app.killedByAm) {
5238                 Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5239                         + ") has died");
5240                 mAllowLowerMemLevel = true;
5241             } else {
5242                 // Note that we always want to do oom adj to update our state with the
5243                 // new number of procs.
5244                 mAllowLowerMemLevel = false;
5245                 doLowMem = false;
5246             }
5247             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5248             if (DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
5249                 "Dying app: " + app + ", pid: " + pid + ", thread: " + thread.asBinder());
5250             handleAppDiedLocked(app, false, true);
5251
5252             if (doOomAdj) {
5253                 updateOomAdjLocked();
5254             }
5255             if (doLowMem) {
5256                 doLowMemReportIfNeededLocked(app);
5257             }
5258         } else if (app.pid != pid) {
5259             // A new process has already been started.
5260             Slog.i(TAG, "Process " + app.processName + " (pid " + pid
5261                     + ") has died and restarted (pid " + app.pid + ").");
5262             EventLog.writeEvent(EventLogTags.AM_PROC_DIED, app.userId, app.pid, app.processName);
5263         } else if (DEBUG_PROCESSES) {
5264             Slog.d(TAG_PROCESSES, "Received spurious death notification for thread "
5265                     + thread.asBinder());
5266         }
5267     }
5268
5269     /**
5270      * If a stack trace dump file is configured, dump process stack traces.
5271      * @param clearTraces causes the dump file to be erased prior to the new
5272      *    traces being written, if true; when false, the new traces will be
5273      *    appended to any existing file content.
5274      * @param firstPids of dalvik VM processes to dump stack traces for first
5275      * @param lastPids of dalvik VM processes to dump stack traces for last
5276      * @param nativeProcs optional list of native process names to dump stack crawls
5277      * @return file containing stack traces, or null if no dump file is configured
5278      */
5279     public static File dumpStackTraces(boolean clearTraces, ArrayList<Integer> firstPids,
5280             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5281         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5282         if (tracesPath == null || tracesPath.length() == 0) {
5283             return null;
5284         }
5285
5286         File tracesFile = new File(tracesPath);
5287         try {
5288             if (clearTraces && tracesFile.exists()) tracesFile.delete();
5289             tracesFile.createNewFile();
5290             FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5291         } catch (IOException e) {
5292             Slog.w(TAG, "Unable to prepare ANR traces file: " + tracesPath, e);
5293             return null;
5294         }
5295
5296         dumpStackTraces(tracesPath, firstPids, processCpuTracker, lastPids, nativeProcs);
5297         return tracesFile;
5298     }
5299
5300     private static void dumpStackTraces(String tracesPath, ArrayList<Integer> firstPids,
5301             ProcessCpuTracker processCpuTracker, SparseArray<Boolean> lastPids, String[] nativeProcs) {
5302         // Use a FileObserver to detect when traces finish writing.
5303         // The order of traces is considered important to maintain for legibility.
5304         FileObserver observer = new FileObserver(tracesPath, FileObserver.CLOSE_WRITE) {
5305             @Override
5306             public synchronized void onEvent(int event, String path) { notify(); }
5307         };
5308
5309         try {
5310             observer.startWatching();
5311
5312             // First collect all of the stacks of the most important pids.
5313             if (firstPids != null) {
5314                 try {
5315                     int num = firstPids.size();
5316                     for (int i = 0; i < num; i++) {
5317                         synchronized (observer) {
5318                             if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for pid "
5319                                     + firstPids.get(i));
5320                             final long sime = SystemClock.elapsedRealtime();
5321                             Process.sendSignal(firstPids.get(i), Process.SIGNAL_QUIT);
5322                             observer.wait(1000);  // Wait for write-close, give up after 1 sec
5323                             if (DEBUG_ANR) Slog.d(TAG, "Done with pid " + firstPids.get(i)
5324                                     + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5325                         }
5326                     }
5327                 } catch (InterruptedException e) {
5328                     Slog.wtf(TAG, e);
5329                 }
5330             }
5331
5332             // Next collect the stacks of the native pids
5333             if (nativeProcs != null) {
5334                 int[] pids = Process.getPidsForCommands(nativeProcs);
5335                 if (pids != null) {
5336                     for (int pid : pids) {
5337                         if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for native pid " + pid);
5338                         final long sime = SystemClock.elapsedRealtime();
5339                         Debug.dumpNativeBacktraceToFile(pid, tracesPath);
5340                         if (DEBUG_ANR) Slog.d(TAG, "Done with native pid " + pid
5341                                 + " in " + (SystemClock.elapsedRealtime()-sime) + "ms");
5342                     }
5343                 }
5344             }
5345
5346             // Lastly, measure CPU usage.
5347             if (processCpuTracker != null) {
5348                 processCpuTracker.init();
5349                 System.gc();
5350                 processCpuTracker.update();
5351                 try {
5352                     synchronized (processCpuTracker) {
5353                         processCpuTracker.wait(500); // measure over 1/2 second.
5354                     }
5355                 } catch (InterruptedException e) {
5356                 }
5357                 processCpuTracker.update();
5358
5359                 // We'll take the stack crawls of just the top apps using CPU.
5360                 final int N = processCpuTracker.countWorkingStats();
5361                 int numProcs = 0;
5362                 for (int i=0; i<N && numProcs<5; i++) {
5363                     ProcessCpuTracker.Stats stats = processCpuTracker.getWorkingStats(i);
5364                     if (lastPids.indexOfKey(stats.pid) >= 0) {
5365                         numProcs++;
5366                         try {
5367                             synchronized (observer) {
5368                                 if (DEBUG_ANR) Slog.d(TAG, "Collecting stacks for extra pid "
5369                                         + stats.pid);
5370                                 final long stime = SystemClock.elapsedRealtime();
5371                                 Process.sendSignal(stats.pid, Process.SIGNAL_QUIT);
5372                                 observer.wait(1000);  // Wait for write-close, give up after 1 sec
5373                                 if (DEBUG_ANR) Slog.d(TAG, "Done with extra pid " + stats.pid
5374                                         + " in " + (SystemClock.elapsedRealtime()-stime) + "ms");
5375                             }
5376                         } catch (InterruptedException e) {
5377                             Slog.wtf(TAG, e);
5378                         }
5379                     } else if (DEBUG_ANR) {
5380                         Slog.d(TAG, "Skipping next CPU consuming process, not a java proc: "
5381                                 + stats.pid);
5382                     }
5383                 }
5384             }
5385         } finally {
5386             observer.stopWatching();
5387         }
5388     }
5389
5390     final void logAppTooSlow(ProcessRecord app, long startTime, String msg) {
5391         if (true || IS_USER_BUILD) {
5392             return;
5393         }
5394         String tracesPath = SystemProperties.get("dalvik.vm.stack-trace-file", null);
5395         if (tracesPath == null || tracesPath.length() == 0) {
5396             return;
5397         }
5398
5399         StrictMode.ThreadPolicy oldPolicy = StrictMode.allowThreadDiskReads();
5400         StrictMode.allowThreadDiskWrites();
5401         try {
5402             final File tracesFile = new File(tracesPath);
5403             final File tracesDir = tracesFile.getParentFile();
5404             final File tracesTmp = new File(tracesDir, "__tmp__");
5405             try {
5406                 if (tracesFile.exists()) {
5407                     tracesTmp.delete();
5408                     tracesFile.renameTo(tracesTmp);
5409                 }
5410                 StringBuilder sb = new StringBuilder();
5411                 Time tobj = new Time();
5412                 tobj.set(System.currentTimeMillis());
5413                 sb.append(tobj.format("%Y-%m-%d %H:%M:%S"));
5414                 sb.append(": ");
5415                 TimeUtils.formatDuration(SystemClock.uptimeMillis()-startTime, sb);
5416                 sb.append(" since ");
5417                 sb.append(msg);
5418                 FileOutputStream fos = new FileOutputStream(tracesFile);
5419                 fos.write(sb.toString().getBytes());
5420                 if (app == null) {
5421                     fos.write("\n*** No application process!".getBytes());
5422                 }
5423                 fos.close();
5424                 FileUtils.setPermissions(tracesFile.getPath(), 0666, -1, -1); // -rw-rw-rw-
5425             } catch (IOException e) {
5426                 Slog.w(TAG, "Unable to prepare slow app traces file: " + tracesPath, e);
5427                 return;
5428             }
5429
5430             if (app != null) {
5431                 ArrayList<Integer> firstPids = new ArrayList<Integer>();
5432                 firstPids.add(app.pid);
5433                 dumpStackTraces(tracesPath, firstPids, null, null, null);
5434             }
5435
5436             File lastTracesFile = null;
5437             File curTracesFile = null;
5438             for (int i=9; i>=0; i--) {
5439                 String name = String.format(Locale.US, "slow%02d.txt", i);
5440                 curTracesFile = new File(tracesDir, name);
5441                 if (curTracesFile.exists()) {
5442                     if (lastTracesFile != null) {
5443                         curTracesFile.renameTo(lastTracesFile);
5444                     } else {
5445                         curTracesFile.delete();
5446                     }
5447                 }
5448                 lastTracesFile = curTracesFile;
5449             }
5450             tracesFile.renameTo(curTracesFile);
5451             if (tracesTmp.exists()) {
5452                 tracesTmp.renameTo(tracesFile);
5453             }
5454         } finally {
5455             StrictMode.setThreadPolicy(oldPolicy);
5456         }
5457     }
5458
5459     final void showLaunchWarningLocked(final ActivityRecord cur, final ActivityRecord next) {
5460         if (!mLaunchWarningShown) {
5461             mLaunchWarningShown = true;
5462             mUiHandler.post(new Runnable() {
5463                 @Override
5464                 public void run() {
5465                     synchronized (ActivityManagerService.this) {
5466                         final Dialog d = new LaunchWarningWindow(mContext, cur, next);
5467                         d.show();
5468                         mUiHandler.postDelayed(new Runnable() {
5469                             @Override
5470                             public void run() {
5471                                 synchronized (ActivityManagerService.this) {
5472                                     d.dismiss();
5473                                     mLaunchWarningShown = false;
5474                                 }
5475                             }
5476                         }, 4000);
5477                     }
5478                 }
5479             });
5480         }
5481     }
5482
5483     @Override
5484     public boolean clearApplicationUserData(final String packageName,
5485             final IPackageDataObserver observer, int userId) {
5486         enforceNotIsolatedCaller("clearApplicationUserData");
5487         int uid = Binder.getCallingUid();
5488         int pid = Binder.getCallingPid();
5489         userId = mUserController.handleIncomingUser(pid, uid, userId, false,
5490                 ALLOW_FULL_ONLY, "clearApplicationUserData", null);
5491
5492
5493         long callingId = Binder.clearCallingIdentity();
5494         try {
5495             IPackageManager pm = AppGlobals.getPackageManager();
5496             int pkgUid = -1;
5497             synchronized(this) {
5498                 if (getPackageManagerInternalLocked().isPackageDataProtected(
5499                         userId, packageName)) {
5500                     throw new SecurityException(
5501                             "Cannot clear data for a protected package: " + packageName);
5502                 }
5503
5504                 try {
5505                     pkgUid = pm.getPackageUid(packageName, MATCH_UNINSTALLED_PACKAGES, userId);
5506                 } catch (RemoteException e) {
5507                 }
5508                 if (pkgUid == -1) {
5509                     Slog.w(TAG, "Invalid packageName: " + packageName);
5510                     if (observer != null) {
5511                         try {
5512                             observer.onRemoveCompleted(packageName, false);
5513                         } catch (RemoteException e) {
5514                             Slog.i(TAG, "Observer no longer exists.");
5515                         }
5516                     }
5517                     return false;
5518                 }
5519                 if (uid == pkgUid || checkComponentPermission(
5520                         android.Manifest.permission.CLEAR_APP_USER_DATA,
5521                         pid, uid, -1, true)
5522                         == PackageManager.PERMISSION_GRANTED) {
5523                     forceStopPackageLocked(packageName, pkgUid, "clear data");
5524                 } else {
5525                     throw new SecurityException("PID " + pid + " does not have permission "
5526                             + android.Manifest.permission.CLEAR_APP_USER_DATA + " to clear data"
5527                                     + " of package " + packageName);
5528                 }
5529
5530                 // Remove all tasks match the cleared application package and user
5531                 for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
5532                     final TaskRecord tr = mRecentTasks.get(i);
5533                     final String taskPackageName =
5534                             tr.getBaseIntent().getComponent().getPackageName();
5535                     if (tr.userId != userId) continue;
5536                     if (!taskPackageName.equals(packageName)) continue;
5537                     removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
5538                 }
5539             }
5540
5541             final int pkgUidF = pkgUid;
5542             final int userIdF = userId;
5543             final IPackageDataObserver localObserver = new IPackageDataObserver.Stub() {
5544                 @Override
5545                 public void onRemoveCompleted(String packageName, boolean succeeded)
5546                         throws RemoteException {
5547                     synchronized (ActivityManagerService.this) {
5548                         finishForceStopPackageLocked(packageName, pkgUidF);
5549                     }
5550
5551                     final Intent intent = new Intent(Intent.ACTION_PACKAGE_DATA_CLEARED,
5552                             Uri.fromParts("package", packageName, null));
5553                     intent.putExtra(Intent.EXTRA_UID, pkgUidF);
5554                     intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(pkgUidF));
5555                     broadcastIntentInPackage("android", Process.SYSTEM_UID, intent,
5556                             null, null, 0, null, null, null, null, false, false, userIdF);
5557
5558                     if (observer != null) {
5559                         observer.onRemoveCompleted(packageName, succeeded);
5560                     }
5561                 }
5562             };
5563
5564             try {
5565                 // Clear application user data
5566                 pm.clearApplicationUserData(packageName, localObserver, userId);
5567
5568                 synchronized(this) {
5569                     // Remove all permissions granted from/to this package
5570                     removeUriPermissionsForPackageLocked(packageName, userId, true);
5571                 }
5572
5573                 // Remove all zen rules created by this package; revoke it's zen access.
5574                 INotificationManager inm = NotificationManager.getService();
5575                 inm.removeAutomaticZenRules(packageName);
5576                 inm.setNotificationPolicyAccessGranted(packageName, false);
5577
5578             } catch (RemoteException e) {
5579             }
5580         } finally {
5581             Binder.restoreCallingIdentity(callingId);
5582         }
5583         return true;
5584     }
5585
5586     @Override
5587     public void killBackgroundProcesses(final String packageName, int userId) {
5588         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5589                 != PackageManager.PERMISSION_GRANTED &&
5590                 checkCallingPermission(android.Manifest.permission.RESTART_PACKAGES)
5591                         != PackageManager.PERMISSION_GRANTED) {
5592             String msg = "Permission Denial: killBackgroundProcesses() from pid="
5593                     + Binder.getCallingPid()
5594                     + ", uid=" + Binder.getCallingUid()
5595                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5596             Slog.w(TAG, msg);
5597             throw new SecurityException(msg);
5598         }
5599
5600         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
5601                 userId, true, ALLOW_FULL_ONLY, "killBackgroundProcesses", null);
5602         long callingId = Binder.clearCallingIdentity();
5603         try {
5604             IPackageManager pm = AppGlobals.getPackageManager();
5605             synchronized(this) {
5606                 int appId = -1;
5607                 try {
5608                     appId = UserHandle.getAppId(
5609                             pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId));
5610                 } catch (RemoteException e) {
5611                 }
5612                 if (appId == -1) {
5613                     Slog.w(TAG, "Invalid packageName: " + packageName);
5614                     return;
5615                 }
5616                 killPackageProcessesLocked(packageName, appId, userId,
5617                         ProcessList.SERVICE_ADJ, false, true, true, false, "kill background");
5618             }
5619         } finally {
5620             Binder.restoreCallingIdentity(callingId);
5621         }
5622     }
5623
5624     @Override
5625     public void killAllBackgroundProcesses() {
5626         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5627                 != PackageManager.PERMISSION_GRANTED) {
5628             final String msg = "Permission Denial: killAllBackgroundProcesses() from pid="
5629                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5630                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5631             Slog.w(TAG, msg);
5632             throw new SecurityException(msg);
5633         }
5634
5635         final long callingId = Binder.clearCallingIdentity();
5636         try {
5637             synchronized (this) {
5638                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5639                 final int NP = mProcessNames.getMap().size();
5640                 for (int ip = 0; ip < NP; ip++) {
5641                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5642                     final int NA = apps.size();
5643                     for (int ia = 0; ia < NA; ia++) {
5644                         final ProcessRecord app = apps.valueAt(ia);
5645                         if (app.persistent) {
5646                             // We don't kill persistent processes.
5647                             continue;
5648                         }
5649                         if (app.removed) {
5650                             procs.add(app);
5651                         } else if (app.setAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
5652                             app.removed = true;
5653                             procs.add(app);
5654                         }
5655                     }
5656                 }
5657
5658                 final int N = procs.size();
5659                 for (int i = 0; i < N; i++) {
5660                     removeProcessLocked(procs.get(i), false, true, "kill all background");
5661                 }
5662
5663                 mAllowLowerMemLevel = true;
5664
5665                 updateOomAdjLocked();
5666                 doLowMemReportIfNeededLocked(null);
5667             }
5668         } finally {
5669             Binder.restoreCallingIdentity(callingId);
5670         }
5671     }
5672
5673     /**
5674      * Kills all background processes, except those matching any of the
5675      * specified properties.
5676      *
5677      * @param minTargetSdk the target SDK version at or above which to preserve
5678      *                     processes, or {@code -1} to ignore the target SDK
5679      * @param maxProcState the process state at or below which to preserve
5680      *                     processes, or {@code -1} to ignore the process state
5681      */
5682     private void killAllBackgroundProcessesExcept(int minTargetSdk, int maxProcState) {
5683         if (checkCallingPermission(android.Manifest.permission.KILL_BACKGROUND_PROCESSES)
5684                 != PackageManager.PERMISSION_GRANTED) {
5685             final String msg = "Permission Denial: killAllBackgroundProcessesExcept() from pid="
5686                     + Binder.getCallingPid() + ", uid=" + Binder.getCallingUid()
5687                     + " requires " + android.Manifest.permission.KILL_BACKGROUND_PROCESSES;
5688             Slog.w(TAG, msg);
5689             throw new SecurityException(msg);
5690         }
5691
5692         final long callingId = Binder.clearCallingIdentity();
5693         try {
5694             synchronized (this) {
5695                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
5696                 final int NP = mProcessNames.getMap().size();
5697                 for (int ip = 0; ip < NP; ip++) {
5698                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5699                     final int NA = apps.size();
5700                     for (int ia = 0; ia < NA; ia++) {
5701                         final ProcessRecord app = apps.valueAt(ia);
5702                         if (app.removed) {
5703                             procs.add(app);
5704                         } else if ((minTargetSdk < 0 || app.info.targetSdkVersion < minTargetSdk)
5705                                 && (maxProcState < 0 || app.setProcState > maxProcState)) {
5706                             app.removed = true;
5707                             procs.add(app);
5708                         }
5709                     }
5710                 }
5711
5712                 final int N = procs.size();
5713                 for (int i = 0; i < N; i++) {
5714                     removeProcessLocked(procs.get(i), false, true, "kill all background except");
5715                 }
5716             }
5717         } finally {
5718             Binder.restoreCallingIdentity(callingId);
5719         }
5720     }
5721
5722     @Override
5723     public void forceStopPackage(final String packageName, int userId) {
5724         if (checkCallingPermission(android.Manifest.permission.FORCE_STOP_PACKAGES)
5725                 != PackageManager.PERMISSION_GRANTED) {
5726             String msg = "Permission Denial: forceStopPackage() from pid="
5727                     + Binder.getCallingPid()
5728                     + ", uid=" + Binder.getCallingUid()
5729                     + " requires " + android.Manifest.permission.FORCE_STOP_PACKAGES;
5730             Slog.w(TAG, msg);
5731             throw new SecurityException(msg);
5732         }
5733         final int callingPid = Binder.getCallingPid();
5734         userId = mUserController.handleIncomingUser(callingPid, Binder.getCallingUid(),
5735                 userId, true, ALLOW_FULL_ONLY, "forceStopPackage", null);
5736         long callingId = Binder.clearCallingIdentity();
5737         try {
5738             IPackageManager pm = AppGlobals.getPackageManager();
5739             synchronized(this) {
5740                 int[] users = userId == UserHandle.USER_ALL
5741                         ? mUserController.getUsers() : new int[] { userId };
5742                 for (int user : users) {
5743                     int pkgUid = -1;
5744                     try {
5745                         pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING,
5746                                 user);
5747                     } catch (RemoteException e) {
5748                     }
5749                     if (pkgUid == -1) {
5750                         Slog.w(TAG, "Invalid packageName: " + packageName);
5751                         continue;
5752                     }
5753                     try {
5754                         pm.setPackageStoppedState(packageName, true, user);
5755                     } catch (RemoteException e) {
5756                     } catch (IllegalArgumentException e) {
5757                         Slog.w(TAG, "Failed trying to unstop package "
5758                                 + packageName + ": " + e);
5759                     }
5760                     if (mUserController.isUserRunningLocked(user, 0)) {
5761                         forceStopPackageLocked(packageName, pkgUid, "from pid " + callingPid);
5762                         finishForceStopPackageLocked(packageName, pkgUid);
5763                     }
5764                 }
5765             }
5766         } finally {
5767             Binder.restoreCallingIdentity(callingId);
5768         }
5769     }
5770
5771     @Override
5772     public void addPackageDependency(String packageName) {
5773         synchronized (this) {
5774             int callingPid = Binder.getCallingPid();
5775             if (callingPid == Process.myPid()) {
5776                 //  Yeah, um, no.
5777                 return;
5778             }
5779             ProcessRecord proc;
5780             synchronized (mPidsSelfLocked) {
5781                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
5782             }
5783             if (proc != null) {
5784                 if (proc.pkgDeps == null) {
5785                     proc.pkgDeps = new ArraySet<String>(1);
5786                 }
5787                 proc.pkgDeps.add(packageName);
5788             }
5789         }
5790     }
5791
5792     /*
5793      * The pkg name and app id have to be specified.
5794      */
5795     @Override
5796     public void killApplication(String pkg, int appId, int userId, String reason) {
5797         if (pkg == null) {
5798             return;
5799         }
5800         // Make sure the uid is valid.
5801         if (appId < 0) {
5802             Slog.w(TAG, "Invalid appid specified for pkg : " + pkg);
5803             return;
5804         }
5805         int callerUid = Binder.getCallingUid();
5806         // Only the system server can kill an application
5807         if (UserHandle.getAppId(callerUid) == Process.SYSTEM_UID) {
5808             // Post an aysnc message to kill the application
5809             Message msg = mHandler.obtainMessage(KILL_APPLICATION_MSG);
5810             msg.arg1 = appId;
5811             msg.arg2 = userId;
5812             Bundle bundle = new Bundle();
5813             bundle.putString("pkg", pkg);
5814             bundle.putString("reason", reason);
5815             msg.obj = bundle;
5816             mHandler.sendMessage(msg);
5817         } else {
5818             throw new SecurityException(callerUid + " cannot kill pkg: " +
5819                     pkg);
5820         }
5821     }
5822
5823     @Override
5824     public void closeSystemDialogs(String reason) {
5825         enforceNotIsolatedCaller("closeSystemDialogs");
5826
5827         final int pid = Binder.getCallingPid();
5828         final int uid = Binder.getCallingUid();
5829         final long origId = Binder.clearCallingIdentity();
5830         try {
5831             synchronized (this) {
5832                 // Only allow this from foreground processes, so that background
5833                 // applications can't abuse it to prevent system UI from being shown.
5834                 if (uid >= Process.FIRST_APPLICATION_UID) {
5835                     ProcessRecord proc;
5836                     synchronized (mPidsSelfLocked) {
5837                         proc = mPidsSelfLocked.get(pid);
5838                     }
5839                     if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
5840                         Slog.w(TAG, "Ignoring closeSystemDialogs " + reason
5841                                 + " from background process " + proc);
5842                         return;
5843                     }
5844                 }
5845                 closeSystemDialogsLocked(reason);
5846             }
5847         } finally {
5848             Binder.restoreCallingIdentity(origId);
5849         }
5850     }
5851
5852     void closeSystemDialogsLocked(String reason) {
5853         Intent intent = new Intent(Intent.ACTION_CLOSE_SYSTEM_DIALOGS);
5854         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5855                 | Intent.FLAG_RECEIVER_FOREGROUND);
5856         if (reason != null) {
5857             intent.putExtra("reason", reason);
5858         }
5859         mWindowManager.closeSystemDialogs(reason);
5860
5861         mStackSupervisor.closeSystemDialogsLocked();
5862
5863         broadcastIntentLocked(null, null, intent, null, null, 0, null, null, null,
5864                 AppOpsManager.OP_NONE, null, false, false,
5865                 -1, Process.SYSTEM_UID, UserHandle.USER_ALL);
5866     }
5867
5868     @Override
5869     public Debug.MemoryInfo[] getProcessMemoryInfo(int[] pids) {
5870         enforceNotIsolatedCaller("getProcessMemoryInfo");
5871         Debug.MemoryInfo[] infos = new Debug.MemoryInfo[pids.length];
5872         for (int i=pids.length-1; i>=0; i--) {
5873             ProcessRecord proc;
5874             int oomAdj;
5875             synchronized (this) {
5876                 synchronized (mPidsSelfLocked) {
5877                     proc = mPidsSelfLocked.get(pids[i]);
5878                     oomAdj = proc != null ? proc.setAdj : 0;
5879                 }
5880             }
5881             infos[i] = new Debug.MemoryInfo();
5882             Debug.getMemoryInfo(pids[i], infos[i]);
5883             if (proc != null) {
5884                 synchronized (this) {
5885                     if (proc.thread != null && proc.setAdj == oomAdj) {
5886                         // Record this for posterity if the process has been stable.
5887                         proc.baseProcessTracker.addPss(infos[i].getTotalPss(),
5888                                 infos[i].getTotalUss(), false, proc.pkgList);
5889                     }
5890                 }
5891             }
5892         }
5893         return infos;
5894     }
5895
5896     @Override
5897     public long[] getProcessPss(int[] pids) {
5898         enforceNotIsolatedCaller("getProcessPss");
5899         long[] pss = new long[pids.length];
5900         for (int i=pids.length-1; i>=0; i--) {
5901             ProcessRecord proc;
5902             int oomAdj;
5903             synchronized (this) {
5904                 synchronized (mPidsSelfLocked) {
5905                     proc = mPidsSelfLocked.get(pids[i]);
5906                     oomAdj = proc != null ? proc.setAdj : 0;
5907                 }
5908             }
5909             long[] tmpUss = new long[1];
5910             pss[i] = Debug.getPss(pids[i], tmpUss, null);
5911             if (proc != null) {
5912                 synchronized (this) {
5913                     if (proc.thread != null && proc.setAdj == oomAdj) {
5914                         // Record this for posterity if the process has been stable.
5915                         proc.baseProcessTracker.addPss(pss[i], tmpUss[0], false, proc.pkgList);
5916                     }
5917                 }
5918             }
5919         }
5920         return pss;
5921     }
5922
5923     @Override
5924     public void killApplicationProcess(String processName, int uid) {
5925         if (processName == null) {
5926             return;
5927         }
5928
5929         int callerUid = Binder.getCallingUid();
5930         // Only the system server can kill an application
5931         if (callerUid == Process.SYSTEM_UID) {
5932             synchronized (this) {
5933                 ProcessRecord app = getProcessRecordLocked(processName, uid, true);
5934                 if (app != null && app.thread != null) {
5935                     try {
5936                         app.thread.scheduleSuicide();
5937                     } catch (RemoteException e) {
5938                         // If the other end already died, then our work here is done.
5939                     }
5940                 } else {
5941                     Slog.w(TAG, "Process/uid not found attempting kill of "
5942                             + processName + " / " + uid);
5943                 }
5944             }
5945         } else {
5946             throw new SecurityException(callerUid + " cannot kill app process: " +
5947                     processName);
5948         }
5949     }
5950
5951     private void forceStopPackageLocked(final String packageName, int uid, String reason) {
5952         forceStopPackageLocked(packageName, UserHandle.getAppId(uid), false,
5953                 false, true, false, false, UserHandle.getUserId(uid), reason);
5954     }
5955
5956     private void finishForceStopPackageLocked(final String packageName, int uid) {
5957         Intent intent = new Intent(Intent.ACTION_PACKAGE_RESTARTED,
5958                 Uri.fromParts("package", packageName, null));
5959         if (!mProcessesReady) {
5960             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
5961                     | Intent.FLAG_RECEIVER_FOREGROUND);
5962         }
5963         intent.putExtra(Intent.EXTRA_UID, uid);
5964         intent.putExtra(Intent.EXTRA_USER_HANDLE, UserHandle.getUserId(uid));
5965         broadcastIntentLocked(null, null, intent,
5966                 null, null, 0, null, null, null, AppOpsManager.OP_NONE,
5967                 null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.getUserId(uid));
5968     }
5969
5970
5971     private final boolean killPackageProcessesLocked(String packageName, int appId,
5972             int userId, int minOomAdj, boolean callerWillRestart, boolean allowRestart,
5973             boolean doit, boolean evenPersistent, String reason) {
5974         ArrayList<ProcessRecord> procs = new ArrayList<>();
5975
5976         // Remove all processes this package may have touched: all with the
5977         // same UID (except for the system or root user), and all whose name
5978         // matches the package name.
5979         final int NP = mProcessNames.getMap().size();
5980         for (int ip=0; ip<NP; ip++) {
5981             SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
5982             final int NA = apps.size();
5983             for (int ia=0; ia<NA; ia++) {
5984                 ProcessRecord app = apps.valueAt(ia);
5985                 if (app.persistent && !evenPersistent) {
5986                     // we don't kill persistent processes
5987                     continue;
5988                 }
5989                 if (app.removed) {
5990                     if (doit) {
5991                         procs.add(app);
5992                     }
5993                     continue;
5994                 }
5995
5996                 // Skip process if it doesn't meet our oom adj requirement.
5997                 if (app.setAdj < minOomAdj) {
5998                     continue;
5999                 }
6000
6001                 // If no package is specified, we call all processes under the
6002                 // give user id.
6003                 if (packageName == null) {
6004                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6005                         continue;
6006                     }
6007                     if (appId >= 0 && UserHandle.getAppId(app.uid) != appId) {
6008                         continue;
6009                     }
6010                 // Package has been specified, we want to hit all processes
6011                 // that match it.  We need to qualify this by the processes
6012                 // that are running under the specified app and user ID.
6013                 } else {
6014                     final boolean isDep = app.pkgDeps != null
6015                             && app.pkgDeps.contains(packageName);
6016                     if (!isDep && UserHandle.getAppId(app.uid) != appId) {
6017                         continue;
6018                     }
6019                     if (userId != UserHandle.USER_ALL && app.userId != userId) {
6020                         continue;
6021                     }
6022                     if (!app.pkgList.containsKey(packageName) && !isDep) {
6023                         continue;
6024                     }
6025                 }
6026
6027                 // Process has passed all conditions, kill it!
6028                 if (!doit) {
6029                     return true;
6030                 }
6031                 app.removed = true;
6032                 procs.add(app);
6033             }
6034         }
6035
6036         int N = procs.size();
6037         for (int i=0; i<N; i++) {
6038             removeProcessLocked(procs.get(i), callerWillRestart, allowRestart, reason);
6039         }
6040         updateOomAdjLocked();
6041         return N > 0;
6042     }
6043
6044     private void cleanupDisabledPackageComponentsLocked(
6045             String packageName, int userId, boolean killProcess, String[] changedClasses) {
6046
6047         Set<String> disabledClasses = null;
6048         boolean packageDisabled = false;
6049         IPackageManager pm = AppGlobals.getPackageManager();
6050
6051         if (changedClasses == null) {
6052             // Nothing changed...
6053             return;
6054         }
6055
6056         // Determine enable/disable state of the package and its components.
6057         int enabled = PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6058         for (int i = changedClasses.length - 1; i >= 0; i--) {
6059             final String changedClass = changedClasses[i];
6060
6061             if (changedClass.equals(packageName)) {
6062                 try {
6063                     // Entire package setting changed
6064                     enabled = pm.getApplicationEnabledSetting(packageName,
6065                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6066                 } catch (Exception e) {
6067                     // No such package/component; probably racing with uninstall.  In any
6068                     // event it means we have nothing further to do here.
6069                     return;
6070                 }
6071                 packageDisabled = enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6072                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT;
6073                 if (packageDisabled) {
6074                     // Entire package is disabled.
6075                     // No need to continue to check component states.
6076                     disabledClasses = null;
6077                     break;
6078                 }
6079             } else {
6080                 try {
6081                     enabled = pm.getComponentEnabledSetting(
6082                             new ComponentName(packageName, changedClass),
6083                             (userId != UserHandle.USER_ALL) ? userId : UserHandle.USER_SYSTEM);
6084                 } catch (Exception e) {
6085                     // As above, probably racing with uninstall.
6086                     return;
6087                 }
6088                 if (enabled != PackageManager.COMPONENT_ENABLED_STATE_ENABLED
6089                         && enabled != PackageManager.COMPONENT_ENABLED_STATE_DEFAULT) {
6090                     if (disabledClasses == null) {
6091                         disabledClasses = new ArraySet<>(changedClasses.length);
6092                     }
6093                     disabledClasses.add(changedClass);
6094                 }
6095             }
6096         }
6097
6098         if (!packageDisabled && disabledClasses == null) {
6099             // Nothing to do here...
6100             return;
6101         }
6102
6103         // Clean-up disabled activities.
6104         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6105                 packageName, disabledClasses, true, false, userId) && mBooted) {
6106             mStackSupervisor.resumeFocusedStackTopActivityLocked();
6107             mStackSupervisor.scheduleIdleLocked();
6108         }
6109
6110         // Clean-up disabled tasks
6111         cleanupDisabledPackageTasksLocked(packageName, disabledClasses, userId);
6112
6113         // Clean-up disabled services.
6114         mServices.bringDownDisabledPackageServicesLocked(
6115                 packageName, disabledClasses, userId, false, killProcess, true);
6116
6117         // Clean-up disabled providers.
6118         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6119         mProviderMap.collectPackageProvidersLocked(
6120                 packageName, disabledClasses, true, false, userId, providers);
6121         for (int i = providers.size() - 1; i >= 0; i--) {
6122             removeDyingProviderLocked(null, providers.get(i), true);
6123         }
6124
6125         // Clean-up disabled broadcast receivers.
6126         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6127             mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6128                     packageName, disabledClasses, userId, true);
6129         }
6130
6131     }
6132
6133     final boolean clearBroadcastQueueForUserLocked(int userId) {
6134         boolean didSomething = false;
6135         for (int i = mBroadcastQueues.length - 1; i >= 0; i--) {
6136             didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6137                     null, null, userId, true);
6138         }
6139         return didSomething;
6140     }
6141
6142     final boolean forceStopPackageLocked(String packageName, int appId,
6143             boolean callerWillRestart, boolean purgeCache, boolean doit,
6144             boolean evenPersistent, boolean uninstalling, int userId, String reason) {
6145         int i;
6146
6147         if (userId == UserHandle.USER_ALL && packageName == null) {
6148             Slog.w(TAG, "Can't force stop all processes of all users, that is insane!");
6149         }
6150
6151         if (appId < 0 && packageName != null) {
6152             try {
6153                 appId = UserHandle.getAppId(AppGlobals.getPackageManager()
6154                         .getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, 0));
6155             } catch (RemoteException e) {
6156             }
6157         }
6158
6159         if (doit) {
6160             if (packageName != null) {
6161                 Slog.i(TAG, "Force stopping " + packageName + " appid=" + appId
6162                         + " user=" + userId + ": " + reason);
6163             } else {
6164                 Slog.i(TAG, "Force stopping u" + userId + ": " + reason);
6165             }
6166
6167             mAppErrors.resetProcessCrashTimeLocked(packageName == null, appId, userId);
6168         }
6169
6170         boolean didSomething = killPackageProcessesLocked(packageName, appId, userId,
6171                 ProcessList.INVALID_ADJ, callerWillRestart, true, doit, evenPersistent,
6172                 packageName == null ? ("stop user " + userId) : ("stop " + packageName));
6173
6174         if (mStackSupervisor.finishDisabledPackageActivitiesLocked(
6175                 packageName, null, doit, evenPersistent, userId)) {
6176             if (!doit) {
6177                 return true;
6178             }
6179             didSomething = true;
6180         }
6181
6182         if (mServices.bringDownDisabledPackageServicesLocked(
6183                 packageName, null, userId, evenPersistent, true, doit)) {
6184             if (!doit) {
6185                 return true;
6186             }
6187             didSomething = true;
6188         }
6189
6190         if (packageName == null) {
6191             // Remove all sticky broadcasts from this user.
6192             mStickyBroadcasts.remove(userId);
6193         }
6194
6195         ArrayList<ContentProviderRecord> providers = new ArrayList<>();
6196         if (mProviderMap.collectPackageProvidersLocked(packageName, null, doit, evenPersistent,
6197                 userId, providers)) {
6198             if (!doit) {
6199                 return true;
6200             }
6201             didSomething = true;
6202         }
6203         for (i = providers.size() - 1; i >= 0; i--) {
6204             removeDyingProviderLocked(null, providers.get(i), true);
6205         }
6206
6207         // Remove transient permissions granted from/to this package/user
6208         removeUriPermissionsForPackageLocked(packageName, userId, false);
6209
6210         if (doit) {
6211             for (i = mBroadcastQueues.length - 1; i >= 0; i--) {
6212                 didSomething |= mBroadcastQueues[i].cleanupDisabledPackageReceiversLocked(
6213                         packageName, null, userId, doit);
6214             }
6215         }
6216
6217         if (packageName == null || uninstalling) {
6218             // Remove pending intents.  For now we only do this when force
6219             // stopping users, because we have some problems when doing this
6220             // for packages -- app widgets are not currently cleaned up for
6221             // such packages, so they can be left with bad pending intents.
6222             if (mIntentSenderRecords.size() > 0) {
6223                 Iterator<WeakReference<PendingIntentRecord>> it
6224                         = mIntentSenderRecords.values().iterator();
6225                 while (it.hasNext()) {
6226                     WeakReference<PendingIntentRecord> wpir = it.next();
6227                     if (wpir == null) {
6228                         it.remove();
6229                         continue;
6230                     }
6231                     PendingIntentRecord pir = wpir.get();
6232                     if (pir == null) {
6233                         it.remove();
6234                         continue;
6235                     }
6236                     if (packageName == null) {
6237                         // Stopping user, remove all objects for the user.
6238                         if (pir.key.userId != userId) {
6239                             // Not the same user, skip it.
6240                             continue;
6241                         }
6242                     } else {
6243                         if (UserHandle.getAppId(pir.uid) != appId) {
6244                             // Different app id, skip it.
6245                             continue;
6246                         }
6247                         if (userId != UserHandle.USER_ALL && pir.key.userId != userId) {
6248                             // Different user, skip it.
6249                             continue;
6250                         }
6251                         if (!pir.key.packageName.equals(packageName)) {
6252                             // Different package, skip it.
6253                             continue;
6254                         }
6255                     }
6256                     if (!doit) {
6257                         return true;
6258                     }
6259                     didSomething = true;
6260                     it.remove();
6261                     pir.canceled = true;
6262                     if (pir.key.activity != null && pir.key.activity.pendingResults != null) {
6263                         pir.key.activity.pendingResults.remove(pir.ref);
6264                     }
6265                 }
6266             }
6267         }
6268
6269         if (doit) {
6270             if (purgeCache && packageName != null) {
6271                 AttributeCache ac = AttributeCache.instance();
6272                 if (ac != null) {
6273                     ac.removePackage(packageName);
6274                 }
6275             }
6276             if (mBooted) {
6277                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
6278                 mStackSupervisor.scheduleIdleLocked();
6279             }
6280         }
6281
6282         return didSomething;
6283     }
6284
6285     private final ProcessRecord removeProcessNameLocked(final String name, final int uid) {
6286         return removeProcessNameLocked(name, uid, null);
6287     }
6288
6289     private final ProcessRecord removeProcessNameLocked(final String name, final int uid,
6290             final ProcessRecord expecting) {
6291         ProcessRecord old = mProcessNames.get(name, uid);
6292         // Only actually remove when the currently recorded value matches the
6293         // record that we expected; if it doesn't match then we raced with a
6294         // newly created process and we don't want to destroy the new one.
6295         if ((expecting == null) || (old == expecting)) {
6296             mProcessNames.remove(name, uid);
6297         }
6298         if (old != null && old.uidRecord != null) {
6299             old.uidRecord.numProcs--;
6300             if (old.uidRecord.numProcs == 0) {
6301                 // No more processes using this uid, tell clients it is gone.
6302                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6303                         "No more processes in " + old.uidRecord);
6304                 enqueueUidChangeLocked(old.uidRecord, -1, UidRecord.CHANGE_GONE);
6305                 mActiveUids.remove(uid);
6306                 noteUidProcessState(uid, ActivityManager.PROCESS_STATE_NONEXISTENT);
6307             }
6308             old.uidRecord = null;
6309         }
6310         mIsolatedProcesses.remove(uid);
6311         return old;
6312     }
6313
6314     private final void addProcessNameLocked(ProcessRecord proc) {
6315         // We shouldn't already have a process under this name, but just in case we
6316         // need to clean up whatever may be there now.
6317         ProcessRecord old = removeProcessNameLocked(proc.processName, proc.uid);
6318         if (old == proc && proc.persistent) {
6319             // We are re-adding a persistent process.  Whatevs!  Just leave it there.
6320             Slog.w(TAG, "Re-adding persistent process " + proc);
6321         } else if (old != null) {
6322             Slog.wtf(TAG, "Already have existing proc " + old + " when adding " + proc);
6323         }
6324         UidRecord uidRec = mActiveUids.get(proc.uid);
6325         if (uidRec == null) {
6326             uidRec = new UidRecord(proc.uid);
6327             // This is the first appearance of the uid, report it now!
6328             if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
6329                     "Creating new process uid: " + uidRec);
6330             mActiveUids.put(proc.uid, uidRec);
6331             noteUidProcessState(uidRec.uid, uidRec.curProcState);
6332             enqueueUidChangeLocked(uidRec, -1, UidRecord.CHANGE_ACTIVE);
6333         }
6334         proc.uidRecord = uidRec;
6335
6336         // Reset render thread tid if it was already set, so new process can set it again.
6337         proc.renderThreadTid = 0;
6338         uidRec.numProcs++;
6339         mProcessNames.put(proc.processName, proc.uid, proc);
6340         if (proc.isolated) {
6341             mIsolatedProcesses.put(proc.uid, proc);
6342         }
6343     }
6344
6345     boolean removeProcessLocked(ProcessRecord app,
6346             boolean callerWillRestart, boolean allowRestart, String reason) {
6347         final String name = app.processName;
6348         final int uid = app.uid;
6349         if (DEBUG_PROCESSES) Slog.d(TAG_PROCESSES,
6350             "Force removing proc " + app.toShortString() + " (" + name + "/" + uid + ")");
6351
6352         ProcessRecord old = mProcessNames.get(name, uid);
6353         if (old != app) {
6354             // This process is no longer active, so nothing to do.
6355             Slog.w(TAG, "Ignoring remove of inactive process: " + app);
6356             return false;
6357         }
6358         removeProcessNameLocked(name, uid);
6359         if (mHeavyWeightProcess == app) {
6360             mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6361                     mHeavyWeightProcess.userId, 0));
6362             mHeavyWeightProcess = null;
6363         }
6364         boolean needRestart = false;
6365         if (app.pid > 0 && app.pid != MY_PID) {
6366             int pid = app.pid;
6367             synchronized (mPidsSelfLocked) {
6368                 mPidsSelfLocked.remove(pid);
6369                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6370             }
6371             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6372             if (app.isolated) {
6373                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6374             }
6375             boolean willRestart = false;
6376             if (app.persistent && !app.isolated) {
6377                 if (!callerWillRestart) {
6378                     willRestart = true;
6379                 } else {
6380                     needRestart = true;
6381                 }
6382             }
6383             app.kill(reason, true);
6384             handleAppDiedLocked(app, willRestart, allowRestart);
6385             if (willRestart) {
6386                 removeLruProcessLocked(app);
6387                 addAppLocked(app.info, false, null /* ABI override */);
6388             }
6389         } else {
6390             mRemovedProcesses.add(app);
6391         }
6392
6393         return needRestart;
6394     }
6395
6396     private final void processContentProviderPublishTimedOutLocked(ProcessRecord app) {
6397         cleanupAppInLaunchingProvidersLocked(app, true);
6398         removeProcessLocked(app, false, true, "timeout publishing content providers");
6399     }
6400
6401     private final void processStartTimedOutLocked(ProcessRecord app) {
6402         final int pid = app.pid;
6403         boolean gone = false;
6404         synchronized (mPidsSelfLocked) {
6405             ProcessRecord knownApp = mPidsSelfLocked.get(pid);
6406             if (knownApp != null && knownApp.thread == null) {
6407                 mPidsSelfLocked.remove(pid);
6408                 gone = true;
6409             }
6410         }
6411
6412         if (gone) {
6413             Slog.w(TAG, "Process " + app + " failed to attach");
6414             EventLog.writeEvent(EventLogTags.AM_PROCESS_START_TIMEOUT, app.userId,
6415                     pid, app.uid, app.processName);
6416             removeProcessNameLocked(app.processName, app.uid);
6417             if (mHeavyWeightProcess == app) {
6418                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
6419                         mHeavyWeightProcess.userId, 0));
6420                 mHeavyWeightProcess = null;
6421             }
6422             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
6423             if (app.isolated) {
6424                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
6425             }
6426             // Take care of any launching providers waiting for this process.
6427             cleanupAppInLaunchingProvidersLocked(app, true);
6428             // Take care of any services that are waiting for the process.
6429             mServices.processStartTimedOutLocked(app);
6430             app.kill("start timeout", true);
6431             removeLruProcessLocked(app);
6432             if (mBackupTarget != null && mBackupTarget.app.pid == pid) {
6433                 Slog.w(TAG, "Unattached app died before backup, skipping");
6434                 try {
6435                     IBackupManager bm = IBackupManager.Stub.asInterface(
6436                             ServiceManager.getService(Context.BACKUP_SERVICE));
6437                     bm.agentDisconnected(app.info.packageName);
6438                 } catch (RemoteException e) {
6439                     // Can't happen; the backup manager is local
6440                 }
6441             }
6442             if (isPendingBroadcastProcessLocked(pid)) {
6443                 Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
6444                 skipPendingBroadcastLocked(pid);
6445             }
6446         } else {
6447             Slog.w(TAG, "Spurious process start timeout - pid not known for " + app);
6448         }
6449     }
6450
6451     private final boolean attachApplicationLocked(IApplicationThread thread,
6452             int pid) {
6453
6454         // Find the application record that is being attached...  either via
6455         // the pid if we are running in multiple processes, or just pull the
6456         // next app record if we are emulating process with anonymous threads.
6457         ProcessRecord app;
6458         if (pid != MY_PID && pid >= 0) {
6459             synchronized (mPidsSelfLocked) {
6460                 app = mPidsSelfLocked.get(pid);
6461             }
6462         } else {
6463             app = null;
6464         }
6465
6466         if (app == null) {
6467             Slog.w(TAG, "No pending application record for pid " + pid
6468                     + " (IApplicationThread " + thread + "); dropping process");
6469             EventLog.writeEvent(EventLogTags.AM_DROP_PROCESS, pid);
6470             if (pid > 0 && pid != MY_PID) {
6471                 Process.killProcessQuiet(pid);
6472                 //TODO: killProcessGroup(app.info.uid, pid);
6473             } else {
6474                 try {
6475                     thread.scheduleExit();
6476                 } catch (Exception e) {
6477                     // Ignore exceptions.
6478                 }
6479             }
6480             return false;
6481         }
6482
6483         // If this application record is still attached to a previous
6484         // process, clean it up now.
6485         if (app.thread != null) {
6486             handleAppDiedLocked(app, true, true);
6487         }
6488
6489         // Tell the process all about itself.
6490
6491         if (DEBUG_ALL) Slog.v(
6492                 TAG, "Binding process pid " + pid + " to record " + app);
6493
6494         final String processName = app.processName;
6495         try {
6496             AppDeathRecipient adr = new AppDeathRecipient(
6497                     app, pid, thread);
6498             thread.asBinder().linkToDeath(adr, 0);
6499             app.deathRecipient = adr;
6500         } catch (RemoteException e) {
6501             app.resetPackageList(mProcessStats);
6502             startProcessLocked(app, "link fail", processName);
6503             return false;
6504         }
6505
6506         EventLog.writeEvent(EventLogTags.AM_PROC_BOUND, app.userId, app.pid, app.processName);
6507
6508         app.makeActive(thread, mProcessStats);
6509         app.curAdj = app.setAdj = app.verifiedAdj = ProcessList.INVALID_ADJ;
6510         app.curSchedGroup = app.setSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
6511         app.forcingToForeground = null;
6512         updateProcessForegroundLocked(app, false, false);
6513         app.hasShownUi = false;
6514         app.debugging = false;
6515         app.cached = false;
6516         app.killedByAm = false;
6517
6518         // We carefully use the same state that PackageManager uses for
6519         // filtering, since we use this flag to decide if we need to install
6520         // providers when user is unlocked later
6521         app.unlocked = StorageManager.isUserKeyUnlocked(app.userId);
6522
6523         mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
6524
6525         boolean normalMode = mProcessesReady || isAllowedWhileBooting(app.info);
6526         List<ProviderInfo> providers = normalMode ? generateApplicationProvidersLocked(app) : null;
6527
6528         if (providers != null && checkAppInLaunchingProvidersLocked(app)) {
6529             Message msg = mHandler.obtainMessage(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG);
6530             msg.obj = app;
6531             mHandler.sendMessageDelayed(msg, CONTENT_PROVIDER_PUBLISH_TIMEOUT);
6532         }
6533
6534         if (!normalMode) {
6535             Slog.i(TAG, "Launching preboot mode app: " + app);
6536         }
6537
6538         if (DEBUG_ALL) Slog.v(
6539             TAG, "New app record " + app
6540             + " thread=" + thread.asBinder() + " pid=" + pid);
6541         try {
6542             int testMode = IApplicationThread.DEBUG_OFF;
6543             if (mDebugApp != null && mDebugApp.equals(processName)) {
6544                 testMode = mWaitForDebugger
6545                     ? IApplicationThread.DEBUG_WAIT
6546                     : IApplicationThread.DEBUG_ON;
6547                 app.debugging = true;
6548                 if (mDebugTransient) {
6549                     mDebugApp = mOrigDebugApp;
6550                     mWaitForDebugger = mOrigWaitForDebugger;
6551                 }
6552             }
6553             String profileFile = app.instrumentationProfileFile;
6554             ParcelFileDescriptor profileFd = null;
6555             int samplingInterval = 0;
6556             boolean profileAutoStop = false;
6557             if (mProfileApp != null && mProfileApp.equals(processName)) {
6558                 mProfileProc = app;
6559                 profileFile = mProfileFile;
6560                 profileFd = mProfileFd;
6561                 samplingInterval = mSamplingInterval;
6562                 profileAutoStop = mAutoStopProfiler;
6563             }
6564             boolean enableTrackAllocation = false;
6565             if (mTrackAllocationApp != null && mTrackAllocationApp.equals(processName)) {
6566                 enableTrackAllocation = true;
6567                 mTrackAllocationApp = null;
6568             }
6569
6570             // If the app is being launched for restore or full backup, set it up specially
6571             boolean isRestrictedBackupMode = false;
6572             if (mBackupTarget != null && mBackupAppName.equals(processName)) {
6573                 isRestrictedBackupMode = mBackupTarget.appInfo.uid >= Process.FIRST_APPLICATION_UID
6574                         && ((mBackupTarget.backupMode == BackupRecord.RESTORE)
6575                                 || (mBackupTarget.backupMode == BackupRecord.RESTORE_FULL)
6576                                 || (mBackupTarget.backupMode == BackupRecord.BACKUP_FULL));
6577             }
6578
6579             if (app.instrumentationClass != null) {
6580                 notifyPackageUse(app.instrumentationClass.getPackageName(),
6581                                  PackageManager.NOTIFY_PACKAGE_USE_INSTRUMENTATION);
6582             }
6583             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Binding proc "
6584                     + processName + " with config " + mConfiguration);
6585             ApplicationInfo appInfo = app.instrumentationInfo != null
6586                     ? app.instrumentationInfo : app.info;
6587             app.compat = compatibilityInfoForPackageLocked(appInfo);
6588             if (profileFd != null) {
6589                 profileFd = profileFd.dup();
6590             }
6591             ProfilerInfo profilerInfo = profileFile == null ? null
6592                     : new ProfilerInfo(profileFile, profileFd, samplingInterval, profileAutoStop);
6593             thread.bindApplication(processName, appInfo, providers, app.instrumentationClass,
6594                     profilerInfo, app.instrumentationArguments, app.instrumentationWatcher,
6595                     app.instrumentationUiAutomationConnection, testMode,
6596                     mBinderTransactionTrackingEnabled, enableTrackAllocation,
6597                     isRestrictedBackupMode || !normalMode, app.persistent,
6598                     new Configuration(mConfiguration), app.compat,
6599                     getCommonServicesLocked(app.isolated),
6600                     mCoreSettingsObserver.getCoreSettingsLocked());
6601             updateLruProcessLocked(app, false, null);
6602             app.lastRequestedGc = app.lastLowMemory = SystemClock.uptimeMillis();
6603         } catch (Exception e) {
6604             // todo: Yikes!  What should we do?  For now we will try to
6605             // start another process, but that could easily get us in
6606             // an infinite loop of restarting processes...
6607             Slog.wtf(TAG, "Exception thrown during bind of " + app, e);
6608
6609             app.resetPackageList(mProcessStats);
6610             app.unlinkDeathRecipient();
6611             startProcessLocked(app, "bind fail", processName);
6612             return false;
6613         }
6614
6615         // Remove this record from the list of starting applications.
6616         mPersistentStartingProcesses.remove(app);
6617         if (DEBUG_PROCESSES && mProcessesOnHold.contains(app)) Slog.v(TAG_PROCESSES,
6618                 "Attach application locked removing on hold: " + app);
6619         mProcessesOnHold.remove(app);
6620
6621         boolean badApp = false;
6622         boolean didSomething = false;
6623
6624         // See if the top visible activity is waiting to run in this process...
6625         if (normalMode) {
6626             try {
6627                 if (mStackSupervisor.attachApplicationLocked(app)) {
6628                     didSomething = true;
6629                 }
6630             } catch (Exception e) {
6631                 Slog.wtf(TAG, "Exception thrown launching activities in " + app, e);
6632                 badApp = true;
6633             }
6634         }
6635
6636         // Find any services that should be running in this process...
6637         if (!badApp) {
6638             try {
6639                 didSomething |= mServices.attachApplicationLocked(app, processName);
6640             } catch (Exception e) {
6641                 Slog.wtf(TAG, "Exception thrown starting services in " + app, e);
6642                 badApp = true;
6643             }
6644         }
6645
6646         // Check if a next-broadcast receiver is in this process...
6647         if (!badApp && isPendingBroadcastProcessLocked(pid)) {
6648             try {
6649                 didSomething |= sendPendingBroadcastsLocked(app);
6650             } catch (Exception e) {
6651                 // If the app died trying to launch the receiver we declare it 'bad'
6652                 Slog.wtf(TAG, "Exception thrown dispatching broadcasts in " + app, e);
6653                 badApp = true;
6654             }
6655         }
6656
6657         // Check whether the next backup agent is in this process...
6658         if (!badApp && mBackupTarget != null && mBackupTarget.appInfo.uid == app.uid) {
6659             if (DEBUG_BACKUP) Slog.v(TAG_BACKUP,
6660                     "New app is backup target, launching agent for " + app);
6661             notifyPackageUse(mBackupTarget.appInfo.packageName,
6662                              PackageManager.NOTIFY_PACKAGE_USE_BACKUP);
6663             try {
6664                 thread.scheduleCreateBackupAgent(mBackupTarget.appInfo,
6665                         compatibilityInfoForPackageLocked(mBackupTarget.appInfo),
6666                         mBackupTarget.backupMode);
6667             } catch (Exception e) {
6668                 Slog.wtf(TAG, "Exception thrown creating backup agent in " + app, e);
6669                 badApp = true;
6670             }
6671         }
6672
6673         if (badApp) {
6674             app.kill("error during init", true);
6675             handleAppDiedLocked(app, false, true);
6676             return false;
6677         }
6678
6679         if (!didSomething) {
6680             updateOomAdjLocked();
6681         }
6682
6683         return true;
6684     }
6685
6686     @Override
6687     public final void attachApplication(IApplicationThread thread) {
6688         synchronized (this) {
6689             int callingPid = Binder.getCallingPid();
6690             final long origId = Binder.clearCallingIdentity();
6691             attachApplicationLocked(thread, callingPid);
6692             Binder.restoreCallingIdentity(origId);
6693         }
6694     }
6695
6696     @Override
6697     public final void activityIdle(IBinder token, Configuration config, boolean stopProfiling) {
6698         final long origId = Binder.clearCallingIdentity();
6699         synchronized (this) {
6700             ActivityStack stack = ActivityRecord.getStackLocked(token);
6701             if (stack != null) {
6702                 ActivityRecord r =
6703                         mStackSupervisor.activityIdleInternalLocked(token, false, config);
6704                 if (stopProfiling) {
6705                     if ((mProfileProc == r.app) && (mProfileFd != null)) {
6706                         try {
6707                             mProfileFd.close();
6708                         } catch (IOException e) {
6709                         }
6710                         clearProfilerLocked();
6711                     }
6712                 }
6713             }
6714         }
6715         Binder.restoreCallingIdentity(origId);
6716     }
6717
6718     void postFinishBooting(boolean finishBooting, boolean enableScreen) {
6719         mHandler.sendMessage(mHandler.obtainMessage(FINISH_BOOTING_MSG,
6720                 finishBooting ? 1 : 0, enableScreen ? 1 : 0));
6721     }
6722
6723     void enableScreenAfterBoot() {
6724         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_ENABLE_SCREEN,
6725                 SystemClock.uptimeMillis());
6726         mWindowManager.enableScreenAfterBoot();
6727
6728         synchronized (this) {
6729             updateEventDispatchingLocked();
6730         }
6731     }
6732
6733     @Override
6734     public void showBootMessage(final CharSequence msg, final boolean always) {
6735         if (Binder.getCallingUid() != Process.myUid()) {
6736             throw new SecurityException();
6737         }
6738         mWindowManager.showBootMessage(msg, always);
6739     }
6740
6741     @Override
6742     public void keyguardWaitingForActivityDrawn() {
6743         enforceNotIsolatedCaller("keyguardWaitingForActivityDrawn");
6744         final long token = Binder.clearCallingIdentity();
6745         try {
6746             synchronized (this) {
6747                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6748                 mWindowManager.keyguardWaitingForActivityDrawn();
6749                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6750                     mLockScreenShown = LOCK_SCREEN_LEAVING;
6751                     updateSleepIfNeededLocked();
6752                 }
6753             }
6754         } finally {
6755             Binder.restoreCallingIdentity(token);
6756         }
6757     }
6758
6759     @Override
6760     public void keyguardGoingAway(int flags) {
6761         enforceNotIsolatedCaller("keyguardGoingAway");
6762         final long token = Binder.clearCallingIdentity();
6763         try {
6764             synchronized (this) {
6765                 if (DEBUG_LOCKSCREEN) logLockScreen("");
6766                 mWindowManager.keyguardGoingAway(flags);
6767                 if (mLockScreenShown == LOCK_SCREEN_SHOWN) {
6768                     mLockScreenShown = LOCK_SCREEN_HIDDEN;
6769                     updateSleepIfNeededLocked();
6770
6771                     // Some stack visibility might change (e.g. docked stack)
6772                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
6773                     applyVrModeIfNeededLocked(mFocusedActivity, true);
6774                 }
6775             }
6776         } finally {
6777             Binder.restoreCallingIdentity(token);
6778         }
6779     }
6780
6781     final void finishBooting() {
6782         synchronized (this) {
6783             if (!mBootAnimationComplete) {
6784                 mCallFinishBooting = true;
6785                 return;
6786             }
6787             mCallFinishBooting = false;
6788         }
6789
6790         ArraySet<String> completedIsas = new ArraySet<String>();
6791         for (String abi : Build.SUPPORTED_ABIS) {
6792             Process.establishZygoteConnectionForAbi(abi);
6793             final String instructionSet = VMRuntime.getInstructionSet(abi);
6794             if (!completedIsas.contains(instructionSet)) {
6795                 try {
6796                     mInstaller.markBootComplete(VMRuntime.getInstructionSet(abi));
6797                 } catch (InstallerException e) {
6798                     Slog.w(TAG, "Unable to mark boot complete for abi: " + abi + " (" +
6799                             e.getMessage() +")");
6800                 }
6801                 completedIsas.add(instructionSet);
6802             }
6803         }
6804
6805         IntentFilter pkgFilter = new IntentFilter();
6806         pkgFilter.addAction(Intent.ACTION_QUERY_PACKAGE_RESTART);
6807         pkgFilter.addDataScheme("package");
6808         mContext.registerReceiver(new BroadcastReceiver() {
6809             @Override
6810             public void onReceive(Context context, Intent intent) {
6811                 String[] pkgs = intent.getStringArrayExtra(Intent.EXTRA_PACKAGES);
6812                 if (pkgs != null) {
6813                     for (String pkg : pkgs) {
6814                         synchronized (ActivityManagerService.this) {
6815                             if (forceStopPackageLocked(pkg, -1, false, false, false, false, false,
6816                                     0, "query restart")) {
6817                                 setResultCode(Activity.RESULT_OK);
6818                                 return;
6819                             }
6820                         }
6821                     }
6822                 }
6823             }
6824         }, pkgFilter);
6825
6826         IntentFilter dumpheapFilter = new IntentFilter();
6827         dumpheapFilter.addAction(DumpHeapActivity.ACTION_DELETE_DUMPHEAP);
6828         mContext.registerReceiver(new BroadcastReceiver() {
6829             @Override
6830             public void onReceive(Context context, Intent intent) {
6831                 if (intent.getBooleanExtra(DumpHeapActivity.EXTRA_DELAY_DELETE, false)) {
6832                     mHandler.sendEmptyMessageDelayed(POST_DUMP_HEAP_NOTIFICATION_MSG, 5*60*1000);
6833                 } else {
6834                     mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
6835                 }
6836             }
6837         }, dumpheapFilter);
6838
6839         // Let system services know.
6840         mSystemServiceManager.startBootPhase(SystemService.PHASE_BOOT_COMPLETED);
6841
6842         synchronized (this) {
6843             // Ensure that any processes we had put on hold are now started
6844             // up.
6845             final int NP = mProcessesOnHold.size();
6846             if (NP > 0) {
6847                 ArrayList<ProcessRecord> procs =
6848                     new ArrayList<ProcessRecord>(mProcessesOnHold);
6849                 for (int ip=0; ip<NP; ip++) {
6850                     if (DEBUG_PROCESSES) Slog.v(TAG_PROCESSES, "Starting process on hold: "
6851                             + procs.get(ip));
6852                     startProcessLocked(procs.get(ip), "on-hold", null);
6853                 }
6854             }
6855
6856             if (mFactoryTest != FactoryTest.FACTORY_TEST_LOW_LEVEL) {
6857                 // Start looking for apps that are abusing wake locks.
6858                 Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
6859                 mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
6860                 // Tell anyone interested that we are done booting!
6861                 SystemProperties.set("sys.boot_completed", "1");
6862
6863                 // And trigger dev.bootcomplete if we are not showing encryption progress
6864                 if (!"trigger_restart_min_framework".equals(SystemProperties.get("vold.decrypt"))
6865                     || "".equals(SystemProperties.get("vold.encrypt_progress"))) {
6866                     SystemProperties.set("dev.bootcomplete", "1");
6867                 }
6868                 mUserController.sendBootCompletedLocked(
6869                         new IIntentReceiver.Stub() {
6870                             @Override
6871                             public void performReceive(Intent intent, int resultCode,
6872                                     String data, Bundle extras, boolean ordered,
6873                                     boolean sticky, int sendingUser) {
6874                                 synchronized (ActivityManagerService.this) {
6875                                     requestPssAllProcsLocked(SystemClock.uptimeMillis(),
6876                                             true, false);
6877                                 }
6878                             }
6879                         });
6880                 scheduleStartProfilesLocked();
6881             }
6882         }
6883     }
6884
6885     @Override
6886     public void bootAnimationComplete() {
6887         final boolean callFinishBooting;
6888         synchronized (this) {
6889             callFinishBooting = mCallFinishBooting;
6890             mBootAnimationComplete = true;
6891         }
6892         if (callFinishBooting) {
6893             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6894             finishBooting();
6895             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6896         }
6897     }
6898
6899     final void ensureBootCompleted() {
6900         boolean booting;
6901         boolean enableScreen;
6902         synchronized (this) {
6903             booting = mBooting;
6904             mBooting = false;
6905             enableScreen = !mBooted;
6906             mBooted = true;
6907         }
6908
6909         if (booting) {
6910             Trace.traceBegin(Trace.TRACE_TAG_ACTIVITY_MANAGER, "FinishBooting");
6911             finishBooting();
6912             Trace.traceEnd(Trace.TRACE_TAG_ACTIVITY_MANAGER);
6913         }
6914
6915         if (enableScreen) {
6916             enableScreenAfterBoot();
6917         }
6918     }
6919
6920     @Override
6921     public final void activityResumed(IBinder token) {
6922         final long origId = Binder.clearCallingIdentity();
6923         synchronized(this) {
6924             ActivityStack stack = ActivityRecord.getStackLocked(token);
6925             if (stack != null) {
6926                 stack.activityResumedLocked(token);
6927             }
6928         }
6929         Binder.restoreCallingIdentity(origId);
6930     }
6931
6932     @Override
6933     public final void activityPaused(IBinder token) {
6934         final long origId = Binder.clearCallingIdentity();
6935         synchronized(this) {
6936             ActivityStack stack = ActivityRecord.getStackLocked(token);
6937             if (stack != null) {
6938                 stack.activityPausedLocked(token, false);
6939             }
6940         }
6941         Binder.restoreCallingIdentity(origId);
6942     }
6943
6944     @Override
6945     public final void activityStopped(IBinder token, Bundle icicle,
6946             PersistableBundle persistentState, CharSequence description) {
6947         if (DEBUG_ALL) Slog.v(TAG, "Activity stopped: token=" + token);
6948
6949         // Refuse possible leaked file descriptors
6950         if (icicle != null && icicle.hasFileDescriptors()) {
6951             throw new IllegalArgumentException("File descriptors passed in Bundle");
6952         }
6953
6954         final long origId = Binder.clearCallingIdentity();
6955
6956         synchronized (this) {
6957             ActivityRecord r = ActivityRecord.isInStackLocked(token);
6958             if (r != null) {
6959                 r.task.stack.activityStoppedLocked(r, icicle, persistentState, description);
6960             }
6961         }
6962
6963         trimApplications();
6964
6965         Binder.restoreCallingIdentity(origId);
6966     }
6967
6968     @Override
6969     public final void activityDestroyed(IBinder token) {
6970         if (DEBUG_SWITCH) Slog.v(TAG_SWITCH, "ACTIVITY DESTROYED: " + token);
6971         synchronized (this) {
6972             ActivityStack stack = ActivityRecord.getStackLocked(token);
6973             if (stack != null) {
6974                 stack.activityDestroyedLocked(token, "activityDestroyed");
6975             }
6976         }
6977     }
6978
6979     @Override
6980     public final void activityRelaunched(IBinder token) {
6981         final long origId = Binder.clearCallingIdentity();
6982         synchronized (this) {
6983             mStackSupervisor.activityRelaunchedLocked(token);
6984         }
6985         Binder.restoreCallingIdentity(origId);
6986     }
6987
6988     @Override
6989     public void reportSizeConfigurations(IBinder token, int[] horizontalSizeConfiguration,
6990             int[] verticalSizeConfigurations, int[] smallestSizeConfigurations) {
6991         if (DEBUG_CONFIGURATION) Slog.v(TAG, "Report configuration: " + token + " "
6992                 + horizontalSizeConfiguration + " " + verticalSizeConfigurations);
6993         synchronized (this) {
6994             ActivityRecord record = ActivityRecord.isInStackLocked(token);
6995             if (record == null) {
6996                 throw new IllegalArgumentException("reportSizeConfigurations: ActivityRecord not "
6997                         + "found for: " + token);
6998             }
6999             record.setSizeConfigurations(horizontalSizeConfiguration,
7000                     verticalSizeConfigurations, smallestSizeConfigurations);
7001         }
7002     }
7003
7004     @Override
7005     public final void backgroundResourcesReleased(IBinder token) {
7006         final long origId = Binder.clearCallingIdentity();
7007         try {
7008             synchronized (this) {
7009                 ActivityStack stack = ActivityRecord.getStackLocked(token);
7010                 if (stack != null) {
7011                     stack.backgroundResourcesReleased();
7012                 }
7013             }
7014         } finally {
7015             Binder.restoreCallingIdentity(origId);
7016         }
7017     }
7018
7019     @Override
7020     public final void notifyLaunchTaskBehindComplete(IBinder token) {
7021         mStackSupervisor.scheduleLaunchTaskBehindComplete(token);
7022     }
7023
7024     @Override
7025     public final void notifyEnterAnimationComplete(IBinder token) {
7026         mHandler.sendMessage(mHandler.obtainMessage(ENTER_ANIMATION_COMPLETE_MSG, token));
7027     }
7028
7029     @Override
7030     public String getCallingPackage(IBinder token) {
7031         synchronized (this) {
7032             ActivityRecord r = getCallingRecordLocked(token);
7033             return r != null ? r.info.packageName : null;
7034         }
7035     }
7036
7037     @Override
7038     public ComponentName getCallingActivity(IBinder token) {
7039         synchronized (this) {
7040             ActivityRecord r = getCallingRecordLocked(token);
7041             return r != null ? r.intent.getComponent() : null;
7042         }
7043     }
7044
7045     private ActivityRecord getCallingRecordLocked(IBinder token) {
7046         ActivityRecord r = ActivityRecord.isInStackLocked(token);
7047         if (r == null) {
7048             return null;
7049         }
7050         return r.resultTo;
7051     }
7052
7053     @Override
7054     public ComponentName getActivityClassForToken(IBinder token) {
7055         synchronized(this) {
7056             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7057             if (r == null) {
7058                 return null;
7059             }
7060             return r.intent.getComponent();
7061         }
7062     }
7063
7064     @Override
7065     public String getPackageForToken(IBinder token) {
7066         synchronized(this) {
7067             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7068             if (r == null) {
7069                 return null;
7070             }
7071             return r.packageName;
7072         }
7073     }
7074
7075     @Override
7076     public boolean isRootVoiceInteraction(IBinder token) {
7077         synchronized(this) {
7078             ActivityRecord r = ActivityRecord.isInStackLocked(token);
7079             if (r == null) {
7080                 return false;
7081             }
7082             return r.rootVoiceInteraction;
7083         }
7084     }
7085
7086     @Override
7087     public IIntentSender getIntentSender(int type,
7088             String packageName, IBinder token, String resultWho,
7089             int requestCode, Intent[] intents, String[] resolvedTypes,
7090             int flags, Bundle bOptions, int userId) {
7091         enforceNotIsolatedCaller("getIntentSender");
7092         // Refuse possible leaked file descriptors
7093         if (intents != null) {
7094             if (intents.length < 1) {
7095                 throw new IllegalArgumentException("Intents array length must be >= 1");
7096             }
7097             for (int i=0; i<intents.length; i++) {
7098                 Intent intent = intents[i];
7099                 if (intent != null) {
7100                     if (intent.hasFileDescriptors()) {
7101                         throw new IllegalArgumentException("File descriptors passed in Intent");
7102                     }
7103                     if (type == ActivityManager.INTENT_SENDER_BROADCAST &&
7104                             (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
7105                         throw new IllegalArgumentException(
7106                                 "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
7107                     }
7108                     intents[i] = new Intent(intent);
7109                 }
7110             }
7111             if (resolvedTypes != null && resolvedTypes.length != intents.length) {
7112                 throw new IllegalArgumentException(
7113                         "Intent array length does not match resolvedTypes length");
7114             }
7115         }
7116         if (bOptions != null) {
7117             if (bOptions.hasFileDescriptors()) {
7118                 throw new IllegalArgumentException("File descriptors passed in options");
7119             }
7120         }
7121
7122         synchronized(this) {
7123             int callingUid = Binder.getCallingUid();
7124             int origUserId = userId;
7125             userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
7126                     type == ActivityManager.INTENT_SENDER_BROADCAST,
7127                     ALLOW_NON_FULL, "getIntentSender", null);
7128             if (origUserId == UserHandle.USER_CURRENT) {
7129                 // We don't want to evaluate this until the pending intent is
7130                 // actually executed.  However, we do want to always do the
7131                 // security checking for it above.
7132                 userId = UserHandle.USER_CURRENT;
7133             }
7134             try {
7135                 if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
7136                     final int uid = AppGlobals.getPackageManager().getPackageUid(packageName,
7137                             MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getUserId(callingUid));
7138                     if (!UserHandle.isSameApp(callingUid, uid)) {
7139                         String msg = "Permission Denial: getIntentSender() from pid="
7140                             + Binder.getCallingPid()
7141                             + ", uid=" + Binder.getCallingUid()
7142                             + ", (need uid=" + uid + ")"
7143                             + " is not allowed to send as package " + packageName;
7144                         Slog.w(TAG, msg);
7145                         throw new SecurityException(msg);
7146                     }
7147                 }
7148
7149                 return getIntentSenderLocked(type, packageName, callingUid, userId,
7150                         token, resultWho, requestCode, intents, resolvedTypes, flags, bOptions);
7151
7152             } catch (RemoteException e) {
7153                 throw new SecurityException(e);
7154             }
7155         }
7156     }
7157
7158     IIntentSender getIntentSenderLocked(int type, String packageName,
7159             int callingUid, int userId, IBinder token, String resultWho,
7160             int requestCode, Intent[] intents, String[] resolvedTypes, int flags,
7161             Bundle bOptions) {
7162         if (DEBUG_MU) Slog.v(TAG_MU, "getIntentSenderLocked(): uid=" + callingUid);
7163         ActivityRecord activity = null;
7164         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7165             activity = ActivityRecord.isInStackLocked(token);
7166             if (activity == null) {
7167                 Slog.w(TAG, "Failed createPendingResult: activity " + token + " not in any stack");
7168                 return null;
7169             }
7170             if (activity.finishing) {
7171                 Slog.w(TAG, "Failed createPendingResult: activity " + activity + " is finishing");
7172                 return null;
7173             }
7174         }
7175
7176         // We're going to be splicing together extras before sending, so we're
7177         // okay poking into any contained extras.
7178         if (intents != null) {
7179             for (int i = 0; i < intents.length; i++) {
7180                 intents[i].setDefusable(true);
7181             }
7182         }
7183         Bundle.setDefusable(bOptions, true);
7184
7185         final boolean noCreate = (flags&PendingIntent.FLAG_NO_CREATE) != 0;
7186         final boolean cancelCurrent = (flags&PendingIntent.FLAG_CANCEL_CURRENT) != 0;
7187         final boolean updateCurrent = (flags&PendingIntent.FLAG_UPDATE_CURRENT) != 0;
7188         flags &= ~(PendingIntent.FLAG_NO_CREATE|PendingIntent.FLAG_CANCEL_CURRENT
7189                 |PendingIntent.FLAG_UPDATE_CURRENT);
7190
7191         PendingIntentRecord.Key key = new PendingIntentRecord.Key(
7192                 type, packageName, activity, resultWho,
7193                 requestCode, intents, resolvedTypes, flags, bOptions, userId);
7194         WeakReference<PendingIntentRecord> ref;
7195         ref = mIntentSenderRecords.get(key);
7196         PendingIntentRecord rec = ref != null ? ref.get() : null;
7197         if (rec != null) {
7198             if (!cancelCurrent) {
7199                 if (updateCurrent) {
7200                     if (rec.key.requestIntent != null) {
7201                         rec.key.requestIntent.replaceExtras(intents != null ?
7202                                 intents[intents.length - 1] : null);
7203                     }
7204                     if (intents != null) {
7205                         intents[intents.length-1] = rec.key.requestIntent;
7206                         rec.key.allIntents = intents;
7207                         rec.key.allResolvedTypes = resolvedTypes;
7208                     } else {
7209                         rec.key.allIntents = null;
7210                         rec.key.allResolvedTypes = null;
7211                     }
7212                 }
7213                 return rec;
7214             }
7215             rec.canceled = true;
7216             mIntentSenderRecords.remove(key);
7217         }
7218         if (noCreate) {
7219             return rec;
7220         }
7221         rec = new PendingIntentRecord(this, key, callingUid);
7222         mIntentSenderRecords.put(key, rec.ref);
7223         if (type == ActivityManager.INTENT_SENDER_ACTIVITY_RESULT) {
7224             if (activity.pendingResults == null) {
7225                 activity.pendingResults
7226                         = new HashSet<WeakReference<PendingIntentRecord>>();
7227             }
7228             activity.pendingResults.add(rec.ref);
7229         }
7230         return rec;
7231     }
7232
7233     @Override
7234     public int sendIntentSender(IIntentSender target, int code, Intent intent, String resolvedType,
7235             IIntentReceiver finishedReceiver, String requiredPermission, Bundle options) {
7236         if (target instanceof PendingIntentRecord) {
7237             return ((PendingIntentRecord)target).sendWithResult(code, intent, resolvedType,
7238                     finishedReceiver, requiredPermission, options);
7239         } else {
7240             if (intent == null) {
7241                 // Weird case: someone has given us their own custom IIntentSender, and now
7242                 // they have someone else trying to send to it but of course this isn't
7243                 // really a PendingIntent, so there is no base Intent, and the caller isn't
7244                 // supplying an Intent... but we never want to dispatch a null Intent to
7245                 // a receiver, so um...  let's make something up.
7246                 Slog.wtf(TAG, "Can't use null intent with direct IIntentSender call");
7247                 intent = new Intent(Intent.ACTION_MAIN);
7248             }
7249             try {
7250                 target.send(code, intent, resolvedType, null, requiredPermission, options);
7251             } catch (RemoteException e) {
7252             }
7253             // Platform code can rely on getting a result back when the send is done, but if
7254             // this intent sender is from outside of the system we can't rely on it doing that.
7255             // So instead we don't give it the result receiver, and instead just directly
7256             // report the finish immediately.
7257             if (finishedReceiver != null) {
7258                 try {
7259                     finishedReceiver.performReceive(intent, 0,
7260                             null, null, false, false, UserHandle.getCallingUserId());
7261                 } catch (RemoteException e) {
7262                 }
7263             }
7264             return 0;
7265         }
7266     }
7267
7268     /**
7269      * Whitelists {@code targetUid} to temporarily bypass Power Save mode.
7270      *
7271      * <p>{@code callerUid} must be allowed to request such whitelist by calling
7272      * {@link #addTempPowerSaveWhitelistGrantorUid(int)}.
7273      */
7274     void tempWhitelistAppForPowerSave(int callerPid, int callerUid, int targetUid, long duration) {
7275         if (DEBUG_WHITELISTS) {
7276             Slog.d(TAG, "tempWhitelistAppForPowerSave(" + callerPid + ", " + callerUid + ", "
7277                     + targetUid + ", " + duration + ")");
7278         }
7279         synchronized (mPidsSelfLocked) {
7280             final ProcessRecord pr = mPidsSelfLocked.get(callerPid);
7281             if (pr == null) {
7282                 Slog.w(TAG, "tempWhitelistAppForPowerSave() no ProcessRecord for pid " + callerPid);
7283                 return;
7284             }
7285             if (!pr.whitelistManager) {
7286                 if (DEBUG_WHITELISTS) {
7287                     Slog.d(TAG, "tempWhitelistAppForPowerSave() for target " + targetUid + ": pid "
7288                             + callerPid + " is not allowed");
7289                 }
7290                 return;
7291             }
7292         }
7293
7294         final long token = Binder.clearCallingIdentity();
7295         try {
7296             mLocalDeviceIdleController.addPowerSaveTempWhitelistAppDirect(targetUid, duration,
7297                     true, "pe from uid:" + callerUid);
7298         } finally {
7299             Binder.restoreCallingIdentity(token);
7300         }
7301     }
7302
7303     @Override
7304     public void cancelIntentSender(IIntentSender sender) {
7305         if (!(sender instanceof PendingIntentRecord)) {
7306             return;
7307         }
7308         synchronized(this) {
7309             PendingIntentRecord rec = (PendingIntentRecord)sender;
7310             try {
7311                 final int uid = AppGlobals.getPackageManager().getPackageUid(rec.key.packageName,
7312                         MATCH_DEBUG_TRIAGED_MISSING, UserHandle.getCallingUserId());
7313                 if (!UserHandle.isSameApp(uid, Binder.getCallingUid())) {
7314                     String msg = "Permission Denial: cancelIntentSender() from pid="
7315                         + Binder.getCallingPid()
7316                         + ", uid=" + Binder.getCallingUid()
7317                         + " is not allowed to cancel packges "
7318                         + rec.key.packageName;
7319                     Slog.w(TAG, msg);
7320                     throw new SecurityException(msg);
7321                 }
7322             } catch (RemoteException e) {
7323                 throw new SecurityException(e);
7324             }
7325             cancelIntentSenderLocked(rec, true);
7326         }
7327     }
7328
7329     void cancelIntentSenderLocked(PendingIntentRecord rec, boolean cleanActivity) {
7330         rec.canceled = true;
7331         mIntentSenderRecords.remove(rec.key);
7332         if (cleanActivity && rec.key.activity != null) {
7333             rec.key.activity.pendingResults.remove(rec.ref);
7334         }
7335     }
7336
7337     @Override
7338     public String getPackageForIntentSender(IIntentSender pendingResult) {
7339         if (!(pendingResult instanceof PendingIntentRecord)) {
7340             return null;
7341         }
7342         try {
7343             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7344             return res.key.packageName;
7345         } catch (ClassCastException e) {
7346         }
7347         return null;
7348     }
7349
7350     @Override
7351     public int getUidForIntentSender(IIntentSender sender) {
7352         if (sender instanceof PendingIntentRecord) {
7353             try {
7354                 PendingIntentRecord res = (PendingIntentRecord)sender;
7355                 return res.uid;
7356             } catch (ClassCastException e) {
7357             }
7358         }
7359         return -1;
7360     }
7361
7362     @Override
7363     public boolean isIntentSenderTargetedToPackage(IIntentSender pendingResult) {
7364         if (!(pendingResult instanceof PendingIntentRecord)) {
7365             return false;
7366         }
7367         try {
7368             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7369             if (res.key.allIntents == null) {
7370                 return false;
7371             }
7372             for (int i=0; i<res.key.allIntents.length; i++) {
7373                 Intent intent = res.key.allIntents[i];
7374                 if (intent.getPackage() != null && intent.getComponent() != null) {
7375                     return false;
7376                 }
7377             }
7378             return true;
7379         } catch (ClassCastException e) {
7380         }
7381         return false;
7382     }
7383
7384     @Override
7385     public boolean isIntentSenderAnActivity(IIntentSender pendingResult) {
7386         if (!(pendingResult instanceof PendingIntentRecord)) {
7387             return false;
7388         }
7389         try {
7390             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7391             if (res.key.type == ActivityManager.INTENT_SENDER_ACTIVITY) {
7392                 return true;
7393             }
7394             return false;
7395         } catch (ClassCastException e) {
7396         }
7397         return false;
7398     }
7399
7400     @Override
7401     public Intent getIntentForIntentSender(IIntentSender pendingResult) {
7402         enforceCallingPermission(Manifest.permission.GET_INTENT_SENDER_INTENT,
7403                 "getIntentForIntentSender()");
7404         if (!(pendingResult instanceof PendingIntentRecord)) {
7405             return null;
7406         }
7407         try {
7408             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7409             return res.key.requestIntent != null ? new Intent(res.key.requestIntent) : null;
7410         } catch (ClassCastException e) {
7411         }
7412         return null;
7413     }
7414
7415     @Override
7416     public String getTagForIntentSender(IIntentSender pendingResult, String prefix) {
7417         if (!(pendingResult instanceof PendingIntentRecord)) {
7418             return null;
7419         }
7420         try {
7421             PendingIntentRecord res = (PendingIntentRecord)pendingResult;
7422             synchronized (this) {
7423                 return getTagForIntentSenderLocked(res, prefix);
7424             }
7425         } catch (ClassCastException e) {
7426         }
7427         return null;
7428     }
7429
7430     String getTagForIntentSenderLocked(PendingIntentRecord res, String prefix) {
7431         final Intent intent = res.key.requestIntent;
7432         if (intent != null) {
7433             if (res.lastTag != null && res.lastTagPrefix == prefix && (res.lastTagPrefix == null
7434                     || res.lastTagPrefix.equals(prefix))) {
7435                 return res.lastTag;
7436             }
7437             res.lastTagPrefix = prefix;
7438             final StringBuilder sb = new StringBuilder(128);
7439             if (prefix != null) {
7440                 sb.append(prefix);
7441             }
7442             if (intent.getAction() != null) {
7443                 sb.append(intent.getAction());
7444             } else if (intent.getComponent() != null) {
7445                 intent.getComponent().appendShortString(sb);
7446             } else {
7447                 sb.append("?");
7448             }
7449             return res.lastTag = sb.toString();
7450         }
7451         return null;
7452     }
7453
7454     @Override
7455     public void setProcessLimit(int max) {
7456         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7457                 "setProcessLimit()");
7458         synchronized (this) {
7459             mProcessLimit = max < 0 ? ProcessList.MAX_CACHED_APPS : max;
7460             mProcessLimitOverride = max;
7461         }
7462         trimApplications();
7463     }
7464
7465     @Override
7466     public int getProcessLimit() {
7467         synchronized (this) {
7468             return mProcessLimitOverride;
7469         }
7470     }
7471
7472     void foregroundTokenDied(ForegroundToken token) {
7473         synchronized (ActivityManagerService.this) {
7474             synchronized (mPidsSelfLocked) {
7475                 ForegroundToken cur
7476                     = mForegroundProcesses.get(token.pid);
7477                 if (cur != token) {
7478                     return;
7479                 }
7480                 mForegroundProcesses.remove(token.pid);
7481                 ProcessRecord pr = mPidsSelfLocked.get(token.pid);
7482                 if (pr == null) {
7483                     return;
7484                 }
7485                 pr.forcingToForeground = null;
7486                 updateProcessForegroundLocked(pr, false, false);
7487             }
7488             updateOomAdjLocked();
7489         }
7490     }
7491
7492     @Override
7493     public void setProcessForeground(IBinder token, int pid, boolean isForeground) {
7494         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
7495                 "setProcessForeground()");
7496         synchronized(this) {
7497             boolean changed = false;
7498
7499             synchronized (mPidsSelfLocked) {
7500                 ProcessRecord pr = mPidsSelfLocked.get(pid);
7501                 if (pr == null && isForeground) {
7502                     Slog.w(TAG, "setProcessForeground called on unknown pid: " + pid);
7503                     return;
7504                 }
7505                 ForegroundToken oldToken = mForegroundProcesses.get(pid);
7506                 if (oldToken != null) {
7507                     oldToken.token.unlinkToDeath(oldToken, 0);
7508                     mForegroundProcesses.remove(pid);
7509                     if (pr != null) {
7510                         pr.forcingToForeground = null;
7511                     }
7512                     changed = true;
7513                 }
7514                 if (isForeground && token != null) {
7515                     ForegroundToken newToken = new ForegroundToken() {
7516                         @Override
7517                         public void binderDied() {
7518                             foregroundTokenDied(this);
7519                         }
7520                     };
7521                     newToken.pid = pid;
7522                     newToken.token = token;
7523                     try {
7524                         token.linkToDeath(newToken, 0);
7525                         mForegroundProcesses.put(pid, newToken);
7526                         pr.forcingToForeground = token;
7527                         changed = true;
7528                     } catch (RemoteException e) {
7529                         // If the process died while doing this, we will later
7530                         // do the cleanup with the process death link.
7531                     }
7532                 }
7533             }
7534
7535             if (changed) {
7536                 updateOomAdjLocked();
7537             }
7538         }
7539     }
7540
7541     @Override
7542     public boolean isAppForeground(int uid) throws RemoteException {
7543         synchronized (this) {
7544             UidRecord uidRec = mActiveUids.get(uid);
7545             if (uidRec == null || uidRec.idle) {
7546                 return false;
7547             }
7548             return uidRec.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
7549         }
7550     }
7551
7552     // NOTE: this is an internal method used by the OnShellCommand implementation only and should
7553     // be guarded by permission checking.
7554     int getUidState(int uid) {
7555         synchronized (this) {
7556             UidRecord uidRec = mActiveUids.get(uid);
7557             return uidRec == null ? ActivityManager.PROCESS_STATE_NONEXISTENT : uidRec.curProcState;
7558         }
7559     }
7560
7561     @Override
7562     public boolean isInMultiWindowMode(IBinder token) {
7563         final long origId = Binder.clearCallingIdentity();
7564         try {
7565             synchronized(this) {
7566                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
7567                 if (r == null) {
7568                     return false;
7569                 }
7570                 // An activity is consider to be in multi-window mode if its task isn't fullscreen.
7571                 return !r.task.mFullscreen;
7572             }
7573         } finally {
7574             Binder.restoreCallingIdentity(origId);
7575         }
7576     }
7577
7578     @Override
7579     public boolean isInPictureInPictureMode(IBinder token) {
7580         final long origId = Binder.clearCallingIdentity();
7581         try {
7582             synchronized(this) {
7583                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
7584                 if (stack == null) {
7585                     return false;
7586                 }
7587                 return stack.mStackId == PINNED_STACK_ID;
7588             }
7589         } finally {
7590             Binder.restoreCallingIdentity(origId);
7591         }
7592     }
7593
7594     @Override
7595     public void enterPictureInPictureMode(IBinder token) {
7596         final long origId = Binder.clearCallingIdentity();
7597         try {
7598             synchronized(this) {
7599                 if (!mSupportsPictureInPicture) {
7600                     throw new IllegalStateException("enterPictureInPictureMode: "
7601                             + "Device doesn't support picture-in-picture mode.");
7602                 }
7603
7604                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
7605
7606                 if (r == null) {
7607                     throw new IllegalStateException("enterPictureInPictureMode: "
7608                             + "Can't find activity for token=" + token);
7609                 }
7610
7611                 if (!r.supportsPictureInPicture()) {
7612                     throw new IllegalArgumentException("enterPictureInPictureMode: "
7613                             + "Picture-In-Picture not supported for r=" + r);
7614                 }
7615
7616                 // Use the default launch bounds for pinned stack if it doesn't exist yet or use the
7617                 // current bounds.
7618                 final ActivityStack pinnedStack = mStackSupervisor.getStack(PINNED_STACK_ID);
7619                 final Rect bounds = (pinnedStack != null)
7620                         ? pinnedStack.mBounds : mDefaultPinnedStackBounds;
7621
7622                 mStackSupervisor.moveActivityToPinnedStackLocked(
7623                         r, "enterPictureInPictureMode", bounds);
7624             }
7625         } finally {
7626             Binder.restoreCallingIdentity(origId);
7627         }
7628     }
7629
7630     // =========================================================
7631     // PROCESS INFO
7632     // =========================================================
7633
7634     static class ProcessInfoService extends IProcessInfoService.Stub {
7635         final ActivityManagerService mActivityManagerService;
7636         ProcessInfoService(ActivityManagerService activityManagerService) {
7637             mActivityManagerService = activityManagerService;
7638         }
7639
7640         @Override
7641         public void getProcessStatesFromPids(/*in*/ int[] pids, /*out*/ int[] states) {
7642             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7643                     /*in*/ pids, /*out*/ states, null);
7644         }
7645
7646         @Override
7647         public void getProcessStatesAndOomScoresFromPids(
7648                 /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7649             mActivityManagerService.getProcessStatesAndOomScoresForPIDs(
7650                     /*in*/ pids, /*out*/ states, /*out*/ scores);
7651         }
7652     }
7653
7654     /**
7655      * For each PID in the given input array, write the current process state
7656      * for that process into the states array, or -1 to indicate that no
7657      * process with the given PID exists. If scores array is provided, write
7658      * the oom score for the process into the scores array, with INVALID_ADJ
7659      * indicating the PID doesn't exist.
7660      */
7661     public void getProcessStatesAndOomScoresForPIDs(
7662             /*in*/ int[] pids, /*out*/ int[] states, /*out*/ int[] scores) {
7663         if (scores != null) {
7664             enforceCallingPermission(android.Manifest.permission.GET_PROCESS_STATE_AND_OOM_SCORE,
7665                     "getProcessStatesAndOomScoresForPIDs()");
7666         }
7667
7668         if (pids == null) {
7669             throw new NullPointerException("pids");
7670         } else if (states == null) {
7671             throw new NullPointerException("states");
7672         } else if (pids.length != states.length) {
7673             throw new IllegalArgumentException("pids and states arrays have different lengths!");
7674         } else if (scores != null && pids.length != scores.length) {
7675             throw new IllegalArgumentException("pids and scores arrays have different lengths!");
7676         }
7677
7678         synchronized (mPidsSelfLocked) {
7679             for (int i = 0; i < pids.length; i++) {
7680                 ProcessRecord pr = mPidsSelfLocked.get(pids[i]);
7681                 states[i] = (pr == null) ? ActivityManager.PROCESS_STATE_NONEXISTENT :
7682                         pr.curProcState;
7683                 if (scores != null) {
7684                     scores[i] = (pr == null) ? ProcessList.INVALID_ADJ : pr.curAdj;
7685                 }
7686             }
7687         }
7688     }
7689
7690     // =========================================================
7691     // PERMISSIONS
7692     // =========================================================
7693
7694     static class PermissionController extends IPermissionController.Stub {
7695         ActivityManagerService mActivityManagerService;
7696         PermissionController(ActivityManagerService activityManagerService) {
7697             mActivityManagerService = activityManagerService;
7698         }
7699
7700         @Override
7701         public boolean checkPermission(String permission, int pid, int uid) {
7702             return mActivityManagerService.checkPermission(permission, pid,
7703                     uid) == PackageManager.PERMISSION_GRANTED;
7704         }
7705
7706         @Override
7707         public String[] getPackagesForUid(int uid) {
7708             return mActivityManagerService.mContext.getPackageManager()
7709                     .getPackagesForUid(uid);
7710         }
7711
7712         @Override
7713         public boolean isRuntimePermission(String permission) {
7714             try {
7715                 PermissionInfo info = mActivityManagerService.mContext.getPackageManager()
7716                         .getPermissionInfo(permission, 0);
7717                 return info.protectionLevel == PermissionInfo.PROTECTION_DANGEROUS;
7718             } catch (NameNotFoundException nnfe) {
7719                 Slog.e(TAG, "No such permission: "+ permission, nnfe);
7720             }
7721             return false;
7722         }
7723     }
7724
7725     class IntentFirewallInterface implements IntentFirewall.AMSInterface {
7726         @Override
7727         public int checkComponentPermission(String permission, int pid, int uid,
7728                 int owningUid, boolean exported) {
7729             return ActivityManagerService.this.checkComponentPermission(permission, pid, uid,
7730                     owningUid, exported);
7731         }
7732
7733         @Override
7734         public Object getAMSLock() {
7735             return ActivityManagerService.this;
7736         }
7737     }
7738
7739     /**
7740      * This can be called with or without the global lock held.
7741      */
7742     int checkComponentPermission(String permission, int pid, int uid,
7743             int owningUid, boolean exported) {
7744         if (pid == MY_PID) {
7745             return PackageManager.PERMISSION_GRANTED;
7746         }
7747         return ActivityManager.checkComponentPermission(permission, uid,
7748                 owningUid, exported);
7749     }
7750
7751     /**
7752      * As the only public entry point for permissions checking, this method
7753      * can enforce the semantic that requesting a check on a null global
7754      * permission is automatically denied.  (Internally a null permission
7755      * string is used when calling {@link #checkComponentPermission} in cases
7756      * when only uid-based security is needed.)
7757      *
7758      * This can be called with or without the global lock held.
7759      */
7760     @Override
7761     public int checkPermission(String permission, int pid, int uid) {
7762         if (permission == null) {
7763             return PackageManager.PERMISSION_DENIED;
7764         }
7765         return checkComponentPermission(permission, pid, uid, -1, true);
7766     }
7767
7768     @Override
7769     public int checkPermissionWithToken(String permission, int pid, int uid, IBinder callerToken) {
7770         if (permission == null) {
7771             return PackageManager.PERMISSION_DENIED;
7772         }
7773
7774         // We might be performing an operation on behalf of an indirect binder
7775         // invocation, e.g. via {@link #openContentUri}.  Check and adjust the
7776         // client identity accordingly before proceeding.
7777         Identity tlsIdentity = sCallerIdentity.get();
7778         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
7779             Slog.d(TAG, "checkComponentPermission() adjusting {pid,uid} to {"
7780                     + tlsIdentity.pid + "," + tlsIdentity.uid + "}");
7781             uid = tlsIdentity.uid;
7782             pid = tlsIdentity.pid;
7783         }
7784
7785         return checkComponentPermission(permission, pid, uid, -1, true);
7786     }
7787
7788     /**
7789      * Binder IPC calls go through the public entry point.
7790      * This can be called with or without the global lock held.
7791      */
7792     int checkCallingPermission(String permission) {
7793         return checkPermission(permission,
7794                 Binder.getCallingPid(),
7795                 UserHandle.getAppId(Binder.getCallingUid()));
7796     }
7797
7798     /**
7799      * This can be called with or without the global lock held.
7800      */
7801     void enforceCallingPermission(String permission, String func) {
7802         if (checkCallingPermission(permission)
7803                 == PackageManager.PERMISSION_GRANTED) {
7804             return;
7805         }
7806
7807         String msg = "Permission Denial: " + func + " from pid="
7808                 + Binder.getCallingPid()
7809                 + ", uid=" + Binder.getCallingUid()
7810                 + " requires " + permission;
7811         Slog.w(TAG, msg);
7812         throw new SecurityException(msg);
7813     }
7814
7815     /**
7816      * Determine if UID is holding permissions required to access {@link Uri} in
7817      * the given {@link ProviderInfo}. Final permission checking is always done
7818      * in {@link ContentProvider}.
7819      */
7820     private final boolean checkHoldingPermissionsLocked(
7821             IPackageManager pm, ProviderInfo pi, GrantUri grantUri, int uid, final int modeFlags) {
7822         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7823                 "checkHoldingPermissionsLocked: uri=" + grantUri + " uid=" + uid);
7824         if (UserHandle.getUserId(uid) != grantUri.sourceUserId) {
7825             if (ActivityManager.checkComponentPermission(INTERACT_ACROSS_USERS, uid, -1, true)
7826                     != PERMISSION_GRANTED) {
7827                 return false;
7828             }
7829         }
7830         return checkHoldingPermissionsInternalLocked(pm, pi, grantUri, uid, modeFlags, true);
7831     }
7832
7833     private final boolean checkHoldingPermissionsInternalLocked(IPackageManager pm, ProviderInfo pi,
7834             GrantUri grantUri, int uid, final int modeFlags, boolean considerUidPermissions) {
7835         if (pi.applicationInfo.uid == uid) {
7836             return true;
7837         } else if (!pi.exported) {
7838             return false;
7839         }
7840
7841         boolean readMet = (modeFlags & Intent.FLAG_GRANT_READ_URI_PERMISSION) == 0;
7842         boolean writeMet = (modeFlags & Intent.FLAG_GRANT_WRITE_URI_PERMISSION) == 0;
7843         try {
7844             // check if target holds top-level <provider> permissions
7845             if (!readMet && pi.readPermission != null && considerUidPermissions
7846                     && (pm.checkUidPermission(pi.readPermission, uid) == PERMISSION_GRANTED)) {
7847                 readMet = true;
7848             }
7849             if (!writeMet && pi.writePermission != null && considerUidPermissions
7850                     && (pm.checkUidPermission(pi.writePermission, uid) == PERMISSION_GRANTED)) {
7851                 writeMet = true;
7852             }
7853
7854             // track if unprotected read/write is allowed; any denied
7855             // <path-permission> below removes this ability
7856             boolean allowDefaultRead = pi.readPermission == null;
7857             boolean allowDefaultWrite = pi.writePermission == null;
7858
7859             // check if target holds any <path-permission> that match uri
7860             final PathPermission[] pps = pi.pathPermissions;
7861             if (pps != null) {
7862                 final String path = grantUri.uri.getPath();
7863                 int i = pps.length;
7864                 while (i > 0 && (!readMet || !writeMet)) {
7865                     i--;
7866                     PathPermission pp = pps[i];
7867                     if (pp.match(path)) {
7868                         if (!readMet) {
7869                             final String pprperm = pp.getReadPermission();
7870                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7871                                     "Checking read perm for " + pprperm + " for " + pp.getPath()
7872                                     + ": match=" + pp.match(path)
7873                                     + " check=" + pm.checkUidPermission(pprperm, uid));
7874                             if (pprperm != null) {
7875                                 if (considerUidPermissions && pm.checkUidPermission(pprperm, uid)
7876                                         == PERMISSION_GRANTED) {
7877                                     readMet = true;
7878                                 } else {
7879                                     allowDefaultRead = false;
7880                                 }
7881                             }
7882                         }
7883                         if (!writeMet) {
7884                             final String ppwperm = pp.getWritePermission();
7885                             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
7886                                     "Checking write perm " + ppwperm + " for " + pp.getPath()
7887                                     + ": match=" + pp.match(path)
7888                                     + " check=" + pm.checkUidPermission(ppwperm, uid));
7889                             if (ppwperm != null) {
7890                                 if (considerUidPermissions && pm.checkUidPermission(ppwperm, uid)
7891                                         == PERMISSION_GRANTED) {
7892                                     writeMet = true;
7893                                 } else {
7894                                     allowDefaultWrite = false;
7895                                 }
7896                             }
7897                         }
7898                     }
7899                 }
7900             }
7901
7902             // grant unprotected <provider> read/write, if not blocked by
7903             // <path-permission> above
7904             if (allowDefaultRead) readMet = true;
7905             if (allowDefaultWrite) writeMet = true;
7906
7907         } catch (RemoteException e) {
7908             return false;
7909         }
7910
7911         return readMet && writeMet;
7912     }
7913
7914     public int getAppStartMode(int uid, String packageName) {
7915         synchronized (this) {
7916             return checkAllowBackgroundLocked(uid, packageName, -1, true);
7917         }
7918     }
7919
7920     int checkAllowBackgroundLocked(int uid, String packageName, int callingPid,
7921             boolean allowWhenForeground) {
7922         UidRecord uidRec = mActiveUids.get(uid);
7923         if (!mLenientBackgroundCheck) {
7924             if (!allowWhenForeground || uidRec == null
7925                     || uidRec.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
7926                 if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid,
7927                         packageName) != AppOpsManager.MODE_ALLOWED) {
7928                     return ActivityManager.APP_START_MODE_DELAYED;
7929                 }
7930             }
7931
7932         } else if (uidRec == null || uidRec.idle) {
7933             if (callingPid >= 0) {
7934                 ProcessRecord proc;
7935                 synchronized (mPidsSelfLocked) {
7936                     proc = mPidsSelfLocked.get(callingPid);
7937                 }
7938                 if (proc != null && proc.curProcState < ActivityManager.PROCESS_STATE_RECEIVER) {
7939                     // Whoever is instigating this is in the foreground, so we will allow it
7940                     // to go through.
7941                     return ActivityManager.APP_START_MODE_NORMAL;
7942                 }
7943             }
7944             if (mAppOpsService.noteOperation(AppOpsManager.OP_RUN_IN_BACKGROUND, uid, packageName)
7945                     != AppOpsManager.MODE_ALLOWED) {
7946                 return ActivityManager.APP_START_MODE_DELAYED;
7947             }
7948         }
7949         return ActivityManager.APP_START_MODE_NORMAL;
7950     }
7951
7952     private ProviderInfo getProviderInfoLocked(String authority, int userHandle, int pmFlags) {
7953         ProviderInfo pi = null;
7954         ContentProviderRecord cpr = mProviderMap.getProviderByName(authority, userHandle);
7955         if (cpr != null) {
7956             pi = cpr.info;
7957         } else {
7958             try {
7959                 pi = AppGlobals.getPackageManager().resolveContentProvider(
7960                         authority, PackageManager.GET_URI_PERMISSION_PATTERNS | pmFlags,
7961                         userHandle);
7962             } catch (RemoteException ex) {
7963             }
7964         }
7965         return pi;
7966     }
7967
7968     private UriPermission findUriPermissionLocked(int targetUid, GrantUri grantUri) {
7969         final ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7970         if (targetUris != null) {
7971             return targetUris.get(grantUri);
7972         }
7973         return null;
7974     }
7975
7976     private UriPermission findOrCreateUriPermissionLocked(String sourcePkg,
7977             String targetPkg, int targetUid, GrantUri grantUri) {
7978         ArrayMap<GrantUri, UriPermission> targetUris = mGrantedUriPermissions.get(targetUid);
7979         if (targetUris == null) {
7980             targetUris = Maps.newArrayMap();
7981             mGrantedUriPermissions.put(targetUid, targetUris);
7982         }
7983
7984         UriPermission perm = targetUris.get(grantUri);
7985         if (perm == null) {
7986             perm = new UriPermission(sourcePkg, targetPkg, targetUid, grantUri);
7987             targetUris.put(grantUri, perm);
7988         }
7989
7990         return perm;
7991     }
7992
7993     private final boolean checkUriPermissionLocked(GrantUri grantUri, int uid,
7994             final int modeFlags) {
7995         final boolean persistable = (modeFlags & Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION) != 0;
7996         final int minStrength = persistable ? UriPermission.STRENGTH_PERSISTABLE
7997                 : UriPermission.STRENGTH_OWNED;
7998
7999         // Root gets to do everything.
8000         if (uid == 0) {
8001             return true;
8002         }
8003
8004         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8005         if (perms == null) return false;
8006
8007         // First look for exact match
8008         final UriPermission exactPerm = perms.get(grantUri);
8009         if (exactPerm != null && exactPerm.getStrength(modeFlags) >= minStrength) {
8010             return true;
8011         }
8012
8013         // No exact match, look for prefixes
8014         final int N = perms.size();
8015         for (int i = 0; i < N; i++) {
8016             final UriPermission perm = perms.valueAt(i);
8017             if (perm.uri.prefix && grantUri.uri.isPathPrefixMatch(perm.uri.uri)
8018                     && perm.getStrength(modeFlags) >= minStrength) {
8019                 return true;
8020             }
8021         }
8022
8023         return false;
8024     }
8025
8026     /**
8027      * @param uri This uri must NOT contain an embedded userId.
8028      * @param userId The userId in which the uri is to be resolved.
8029      */
8030     @Override
8031     public int checkUriPermission(Uri uri, int pid, int uid,
8032             final int modeFlags, int userId, IBinder callerToken) {
8033         enforceNotIsolatedCaller("checkUriPermission");
8034
8035         // Another redirected-binder-call permissions check as in
8036         // {@link checkPermissionWithToken}.
8037         Identity tlsIdentity = sCallerIdentity.get();
8038         if (tlsIdentity != null && tlsIdentity.token == callerToken) {
8039             uid = tlsIdentity.uid;
8040             pid = tlsIdentity.pid;
8041         }
8042
8043         // Our own process gets to do everything.
8044         if (pid == MY_PID) {
8045             return PackageManager.PERMISSION_GRANTED;
8046         }
8047         synchronized (this) {
8048             return checkUriPermissionLocked(new GrantUri(userId, uri, false), uid, modeFlags)
8049                     ? PackageManager.PERMISSION_GRANTED
8050                     : PackageManager.PERMISSION_DENIED;
8051         }
8052     }
8053
8054     /**
8055      * Check if the targetPkg can be granted permission to access uri by
8056      * the callingUid using the given modeFlags.  Throws a security exception
8057      * if callingUid is not allowed to do this.  Returns the uid of the target
8058      * if the URI permission grant should be performed; returns -1 if it is not
8059      * needed (for example targetPkg already has permission to access the URI).
8060      * If you already know the uid of the target, you can supply it in
8061      * lastTargetUid else set that to -1.
8062      */
8063     int checkGrantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8064             final int modeFlags, int lastTargetUid) {
8065         if (!Intent.isAccessUriMode(modeFlags)) {
8066             return -1;
8067         }
8068
8069         if (targetPkg != null) {
8070             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8071                     "Checking grant " + targetPkg + " permission to " + grantUri);
8072         }
8073
8074         final IPackageManager pm = AppGlobals.getPackageManager();
8075
8076         // If this is not a content: uri, we can't do anything with it.
8077         if (!ContentResolver.SCHEME_CONTENT.equals(grantUri.uri.getScheme())) {
8078             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8079                     "Can't grant URI permission for non-content URI: " + grantUri);
8080             return -1;
8081         }
8082
8083         final String authority = grantUri.uri.getAuthority();
8084         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8085                 MATCH_DEBUG_TRIAGED_MISSING);
8086         if (pi == null) {
8087             Slog.w(TAG, "No content provider found for permission check: " +
8088                     grantUri.uri.toSafeString());
8089             return -1;
8090         }
8091
8092         int targetUid = lastTargetUid;
8093         if (targetUid < 0 && targetPkg != null) {
8094             try {
8095                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8096                         UserHandle.getUserId(callingUid));
8097                 if (targetUid < 0) {
8098                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8099                             "Can't grant URI permission no uid for: " + targetPkg);
8100                     return -1;
8101                 }
8102             } catch (RemoteException ex) {
8103                 return -1;
8104             }
8105         }
8106
8107         if (targetUid >= 0) {
8108             // First...  does the target actually need this permission?
8109             if (checkHoldingPermissionsLocked(pm, pi, grantUri, targetUid, modeFlags)) {
8110                 // No need to grant the target this permission.
8111                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8112                         "Target " + targetPkg + " already has full permission to " + grantUri);
8113                 return -1;
8114             }
8115         } else {
8116             // First...  there is no target package, so can anyone access it?
8117             boolean allowed = pi.exported;
8118             if ((modeFlags&Intent.FLAG_GRANT_READ_URI_PERMISSION) != 0) {
8119                 if (pi.readPermission != null) {
8120                     allowed = false;
8121                 }
8122             }
8123             if ((modeFlags&Intent.FLAG_GRANT_WRITE_URI_PERMISSION) != 0) {
8124                 if (pi.writePermission != null) {
8125                     allowed = false;
8126                 }
8127             }
8128             if (allowed) {
8129                 return -1;
8130             }
8131         }
8132
8133         /* There is a special cross user grant if:
8134          * - The target is on another user.
8135          * - Apps on the current user can access the uri without any uid permissions.
8136          * In this case, we grant a uri permission, even if the ContentProvider does not normally
8137          * grant uri permissions.
8138          */
8139         boolean specialCrossUserGrant = UserHandle.getUserId(targetUid) != grantUri.sourceUserId
8140                 && checkHoldingPermissionsInternalLocked(pm, pi, grantUri, callingUid,
8141                 modeFlags, false /*without considering the uid permissions*/);
8142
8143         // Second...  is the provider allowing granting of URI permissions?
8144         if (!specialCrossUserGrant) {
8145             if (!pi.grantUriPermissions) {
8146                 throw new SecurityException("Provider " + pi.packageName
8147                         + "/" + pi.name
8148                         + " does not allow granting of Uri permissions (uri "
8149                         + grantUri + ")");
8150             }
8151             if (pi.uriPermissionPatterns != null) {
8152                 final int N = pi.uriPermissionPatterns.length;
8153                 boolean allowed = false;
8154                 for (int i=0; i<N; i++) {
8155                     if (pi.uriPermissionPatterns[i] != null
8156                             && pi.uriPermissionPatterns[i].match(grantUri.uri.getPath())) {
8157                         allowed = true;
8158                         break;
8159                     }
8160                 }
8161                 if (!allowed) {
8162                     throw new SecurityException("Provider " + pi.packageName
8163                             + "/" + pi.name
8164                             + " does not allow granting of permission to path of Uri "
8165                             + grantUri);
8166                 }
8167             }
8168         }
8169
8170         // Third...  does the caller itself have permission to access
8171         // this uri?
8172         if (UserHandle.getAppId(callingUid) != Process.SYSTEM_UID) {
8173             if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8174                 // Require they hold a strong enough Uri permission
8175                 if (!checkUriPermissionLocked(grantUri, callingUid, modeFlags)) {
8176                     throw new SecurityException("Uid " + callingUid
8177                             + " does not have permission to uri " + grantUri);
8178                 }
8179             }
8180         }
8181         return targetUid;
8182     }
8183
8184     /**
8185      * @param uri This uri must NOT contain an embedded userId.
8186      * @param userId The userId in which the uri is to be resolved.
8187      */
8188     @Override
8189     public int checkGrantUriPermission(int callingUid, String targetPkg, Uri uri,
8190             final int modeFlags, int userId) {
8191         enforceNotIsolatedCaller("checkGrantUriPermission");
8192         synchronized(this) {
8193             return checkGrantUriPermissionLocked(callingUid, targetPkg,
8194                     new GrantUri(userId, uri, false), modeFlags, -1);
8195         }
8196     }
8197
8198     void grantUriPermissionUncheckedLocked(int targetUid, String targetPkg, GrantUri grantUri,
8199             final int modeFlags, UriPermissionOwner owner) {
8200         if (!Intent.isAccessUriMode(modeFlags)) {
8201             return;
8202         }
8203
8204         // So here we are: the caller has the assumed permission
8205         // to the uri, and the target doesn't.  Let's now give this to
8206         // the target.
8207
8208         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8209                 "Granting " + targetPkg + "/" + targetUid + " permission to " + grantUri);
8210
8211         final String authority = grantUri.uri.getAuthority();
8212         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8213                 MATCH_DEBUG_TRIAGED_MISSING);
8214         if (pi == null) {
8215             Slog.w(TAG, "No content provider found for grant: " + grantUri.toSafeString());
8216             return;
8217         }
8218
8219         if ((modeFlags & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0) {
8220             grantUri.prefix = true;
8221         }
8222         final UriPermission perm = findOrCreateUriPermissionLocked(
8223                 pi.packageName, targetPkg, targetUid, grantUri);
8224         perm.grantModes(modeFlags, owner);
8225     }
8226
8227     void grantUriPermissionLocked(int callingUid, String targetPkg, GrantUri grantUri,
8228             final int modeFlags, UriPermissionOwner owner, int targetUserId) {
8229         if (targetPkg == null) {
8230             throw new NullPointerException("targetPkg");
8231         }
8232         int targetUid;
8233         final IPackageManager pm = AppGlobals.getPackageManager();
8234         try {
8235             targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING, targetUserId);
8236         } catch (RemoteException ex) {
8237             return;
8238         }
8239
8240         targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, modeFlags,
8241                 targetUid);
8242         if (targetUid < 0) {
8243             return;
8244         }
8245
8246         grantUriPermissionUncheckedLocked(targetUid, targetPkg, grantUri, modeFlags,
8247                 owner);
8248     }
8249
8250     static class NeededUriGrants extends ArrayList<GrantUri> {
8251         final String targetPkg;
8252         final int targetUid;
8253         final int flags;
8254
8255         NeededUriGrants(String targetPkg, int targetUid, int flags) {
8256             this.targetPkg = targetPkg;
8257             this.targetUid = targetUid;
8258             this.flags = flags;
8259         }
8260     }
8261
8262     /**
8263      * Like checkGrantUriPermissionLocked, but takes an Intent.
8264      */
8265     NeededUriGrants checkGrantUriPermissionFromIntentLocked(int callingUid,
8266             String targetPkg, Intent intent, int mode, NeededUriGrants needed, int targetUserId) {
8267         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8268                 "Checking URI perm to data=" + (intent != null ? intent.getData() : null)
8269                 + " clip=" + (intent != null ? intent.getClipData() : null)
8270                 + " from " + intent + "; flags=0x"
8271                 + Integer.toHexString(intent != null ? intent.getFlags() : 0));
8272
8273         if (targetPkg == null) {
8274             throw new NullPointerException("targetPkg");
8275         }
8276
8277         if (intent == null) {
8278             return null;
8279         }
8280         Uri data = intent.getData();
8281         ClipData clip = intent.getClipData();
8282         if (data == null && clip == null) {
8283             return null;
8284         }
8285         // Default userId for uris in the intent (if they don't specify it themselves)
8286         int contentUserHint = intent.getContentUserHint();
8287         if (contentUserHint == UserHandle.USER_CURRENT) {
8288             contentUserHint = UserHandle.getUserId(callingUid);
8289         }
8290         final IPackageManager pm = AppGlobals.getPackageManager();
8291         int targetUid;
8292         if (needed != null) {
8293             targetUid = needed.targetUid;
8294         } else {
8295             try {
8296                 targetUid = pm.getPackageUid(targetPkg, MATCH_DEBUG_TRIAGED_MISSING,
8297                         targetUserId);
8298             } catch (RemoteException ex) {
8299                 return null;
8300             }
8301             if (targetUid < 0) {
8302                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8303                         "Can't grant URI permission no uid for: " + targetPkg
8304                         + " on user " + targetUserId);
8305                 return null;
8306             }
8307         }
8308         if (data != null) {
8309             GrantUri grantUri = GrantUri.resolve(contentUserHint, data);
8310             targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8311                     targetUid);
8312             if (targetUid > 0) {
8313                 if (needed == null) {
8314                     needed = new NeededUriGrants(targetPkg, targetUid, mode);
8315                 }
8316                 needed.add(grantUri);
8317             }
8318         }
8319         if (clip != null) {
8320             for (int i=0; i<clip.getItemCount(); i++) {
8321                 Uri uri = clip.getItemAt(i).getUri();
8322                 if (uri != null) {
8323                     GrantUri grantUri = GrantUri.resolve(contentUserHint, uri);
8324                     targetUid = checkGrantUriPermissionLocked(callingUid, targetPkg, grantUri, mode,
8325                             targetUid);
8326                     if (targetUid > 0) {
8327                         if (needed == null) {
8328                             needed = new NeededUriGrants(targetPkg, targetUid, mode);
8329                         }
8330                         needed.add(grantUri);
8331                     }
8332                 } else {
8333                     Intent clipIntent = clip.getItemAt(i).getIntent();
8334                     if (clipIntent != null) {
8335                         NeededUriGrants newNeeded = checkGrantUriPermissionFromIntentLocked(
8336                                 callingUid, targetPkg, clipIntent, mode, needed, targetUserId);
8337                         if (newNeeded != null) {
8338                             needed = newNeeded;
8339                         }
8340                     }
8341                 }
8342             }
8343         }
8344
8345         return needed;
8346     }
8347
8348     /**
8349      * Like grantUriPermissionUncheckedLocked, but takes an Intent.
8350      */
8351     void grantUriPermissionUncheckedFromIntentLocked(NeededUriGrants needed,
8352             UriPermissionOwner owner) {
8353         if (needed != null) {
8354             for (int i=0; i<needed.size(); i++) {
8355                 GrantUri grantUri = needed.get(i);
8356                 grantUriPermissionUncheckedLocked(needed.targetUid, needed.targetPkg,
8357                         grantUri, needed.flags, owner);
8358             }
8359         }
8360     }
8361
8362     void grantUriPermissionFromIntentLocked(int callingUid,
8363             String targetPkg, Intent intent, UriPermissionOwner owner, int targetUserId) {
8364         NeededUriGrants needed = checkGrantUriPermissionFromIntentLocked(callingUid, targetPkg,
8365                 intent, intent != null ? intent.getFlags() : 0, null, targetUserId);
8366         if (needed == null) {
8367             return;
8368         }
8369
8370         grantUriPermissionUncheckedFromIntentLocked(needed, owner);
8371     }
8372
8373     /**
8374      * @param uri This uri must NOT contain an embedded userId.
8375      * @param userId The userId in which the uri is to be resolved.
8376      */
8377     @Override
8378     public void grantUriPermission(IApplicationThread caller, String targetPkg, Uri uri,
8379             final int modeFlags, int userId) {
8380         enforceNotIsolatedCaller("grantUriPermission");
8381         GrantUri grantUri = new GrantUri(userId, uri, false);
8382         synchronized(this) {
8383             final ProcessRecord r = getRecordForAppLocked(caller);
8384             if (r == null) {
8385                 throw new SecurityException("Unable to find app for caller "
8386                         + caller
8387                         + " when granting permission to uri " + grantUri);
8388             }
8389             if (targetPkg == null) {
8390                 throw new IllegalArgumentException("null target");
8391             }
8392             if (grantUri == null) {
8393                 throw new IllegalArgumentException("null uri");
8394             }
8395
8396             Preconditions.checkFlagsArgument(modeFlags, Intent.FLAG_GRANT_READ_URI_PERMISSION
8397                     | Intent.FLAG_GRANT_WRITE_URI_PERMISSION
8398                     | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION
8399                     | Intent.FLAG_GRANT_PREFIX_URI_PERMISSION);
8400
8401             grantUriPermissionLocked(r.uid, targetPkg, grantUri, modeFlags, null,
8402                     UserHandle.getUserId(r.uid));
8403         }
8404     }
8405
8406     void removeUriPermissionIfNeededLocked(UriPermission perm) {
8407         if (perm.modeFlags == 0) {
8408             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8409                     perm.targetUid);
8410             if (perms != null) {
8411                 if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8412                         "Removing " + perm.targetUid + " permission to " + perm.uri);
8413
8414                 perms.remove(perm.uri);
8415                 if (perms.isEmpty()) {
8416                     mGrantedUriPermissions.remove(perm.targetUid);
8417                 }
8418             }
8419         }
8420     }
8421
8422     private void revokeUriPermissionLocked(int callingUid, GrantUri grantUri, final int modeFlags) {
8423         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8424                 "Revoking all granted permissions to " + grantUri);
8425
8426         final IPackageManager pm = AppGlobals.getPackageManager();
8427         final String authority = grantUri.uri.getAuthority();
8428         final ProviderInfo pi = getProviderInfoLocked(authority, grantUri.sourceUserId,
8429                 MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8430         if (pi == null) {
8431             Slog.w(TAG, "No content provider found for permission revoke: "
8432                     + grantUri.toSafeString());
8433             return;
8434         }
8435
8436         // Does the caller have this permission on the URI?
8437         if (!checkHoldingPermissionsLocked(pm, pi, grantUri, callingUid, modeFlags)) {
8438             // If they don't have direct access to the URI, then revoke any
8439             // ownerless URI permissions that have been granted to them.
8440             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
8441             if (perms != null) {
8442                 boolean persistChanged = false;
8443                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8444                     final UriPermission perm = it.next();
8445                     if (perm.uri.sourceUserId == grantUri.sourceUserId
8446                             && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8447                         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8448                                 "Revoking non-owned " + perm.targetUid
8449                                 + " permission to " + perm.uri);
8450                         persistChanged |= perm.revokeModes(
8451                                 modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, false);
8452                         if (perm.modeFlags == 0) {
8453                             it.remove();
8454                         }
8455                     }
8456                 }
8457                 if (perms.isEmpty()) {
8458                     mGrantedUriPermissions.remove(callingUid);
8459                 }
8460                 if (persistChanged) {
8461                     schedulePersistUriGrants();
8462                 }
8463             }
8464             return;
8465         }
8466
8467         boolean persistChanged = false;
8468
8469         // Go through all of the permissions and remove any that match.
8470         int N = mGrantedUriPermissions.size();
8471         for (int i = 0; i < N; i++) {
8472             final int targetUid = mGrantedUriPermissions.keyAt(i);
8473             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8474
8475             for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8476                 final UriPermission perm = it.next();
8477                 if (perm.uri.sourceUserId == grantUri.sourceUserId
8478                         && perm.uri.uri.isPathPrefixMatch(grantUri.uri)) {
8479                     if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8480                                 "Revoking " + perm.targetUid + " permission to " + perm.uri);
8481                     persistChanged |= perm.revokeModes(
8482                             modeFlags | Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8483                     if (perm.modeFlags == 0) {
8484                         it.remove();
8485                     }
8486                 }
8487             }
8488
8489             if (perms.isEmpty()) {
8490                 mGrantedUriPermissions.remove(targetUid);
8491                 N--;
8492                 i--;
8493             }
8494         }
8495
8496         if (persistChanged) {
8497             schedulePersistUriGrants();
8498         }
8499     }
8500
8501     /**
8502      * @param uri This uri must NOT contain an embedded userId.
8503      * @param userId The userId in which the uri is to be resolved.
8504      */
8505     @Override
8506     public void revokeUriPermission(IApplicationThread caller, Uri uri, final int modeFlags,
8507             int userId) {
8508         enforceNotIsolatedCaller("revokeUriPermission");
8509         synchronized(this) {
8510             final ProcessRecord r = getRecordForAppLocked(caller);
8511             if (r == null) {
8512                 throw new SecurityException("Unable to find app for caller "
8513                         + caller
8514                         + " when revoking permission to uri " + uri);
8515             }
8516             if (uri == null) {
8517                 Slog.w(TAG, "revokeUriPermission: null uri");
8518                 return;
8519             }
8520
8521             if (!Intent.isAccessUriMode(modeFlags)) {
8522                 return;
8523             }
8524
8525             final String authority = uri.getAuthority();
8526             final ProviderInfo pi = getProviderInfoLocked(authority, userId,
8527                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE);
8528             if (pi == null) {
8529                 Slog.w(TAG, "No content provider found for permission revoke: "
8530                         + uri.toSafeString());
8531                 return;
8532             }
8533
8534             revokeUriPermissionLocked(r.uid, new GrantUri(userId, uri, false), modeFlags);
8535         }
8536     }
8537
8538     /**
8539      * Remove any {@link UriPermission} granted <em>from</em> or <em>to</em> the
8540      * given package.
8541      *
8542      * @param packageName Package name to match, or {@code null} to apply to all
8543      *            packages.
8544      * @param userHandle User to match, or {@link UserHandle#USER_ALL} to apply
8545      *            to all users.
8546      * @param persistable If persistable grants should be removed.
8547      */
8548     private void removeUriPermissionsForPackageLocked(
8549             String packageName, int userHandle, boolean persistable) {
8550         if (userHandle == UserHandle.USER_ALL && packageName == null) {
8551             throw new IllegalArgumentException("Must narrow by either package or user");
8552         }
8553
8554         boolean persistChanged = false;
8555
8556         int N = mGrantedUriPermissions.size();
8557         for (int i = 0; i < N; i++) {
8558             final int targetUid = mGrantedUriPermissions.keyAt(i);
8559             final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8560
8561             // Only inspect grants matching user
8562             if (userHandle == UserHandle.USER_ALL
8563                     || userHandle == UserHandle.getUserId(targetUid)) {
8564                 for (Iterator<UriPermission> it = perms.values().iterator(); it.hasNext();) {
8565                     final UriPermission perm = it.next();
8566
8567                     // Only inspect grants matching package
8568                     if (packageName == null || perm.sourcePkg.equals(packageName)
8569                             || perm.targetPkg.equals(packageName)) {
8570                         // Hacky solution as part of fixing a security bug; ignore
8571                         // grants associated with DownloadManager so we don't have
8572                         // to immediately launch it to regrant the permissions
8573                         if (Downloads.Impl.AUTHORITY.equals(perm.uri.uri.getAuthority())
8574                                 && !persistable) continue;
8575
8576                         persistChanged |= perm.revokeModes(persistable
8577                                 ? ~0 : ~Intent.FLAG_GRANT_PERSISTABLE_URI_PERMISSION, true);
8578
8579                         // Only remove when no modes remain; any persisted grants
8580                         // will keep this alive.
8581                         if (perm.modeFlags == 0) {
8582                             it.remove();
8583                         }
8584                     }
8585                 }
8586
8587                 if (perms.isEmpty()) {
8588                     mGrantedUriPermissions.remove(targetUid);
8589                     N--;
8590                     i--;
8591                 }
8592             }
8593         }
8594
8595         if (persistChanged) {
8596             schedulePersistUriGrants();
8597         }
8598     }
8599
8600     @Override
8601     public IBinder newUriPermissionOwner(String name) {
8602         enforceNotIsolatedCaller("newUriPermissionOwner");
8603         synchronized(this) {
8604             UriPermissionOwner owner = new UriPermissionOwner(this, name);
8605             return owner.getExternalTokenLocked();
8606         }
8607     }
8608
8609     @Override
8610     public IBinder getUriPermissionOwnerForActivity(IBinder activityToken) {
8611         enforceNotIsolatedCaller("getUriPermissionOwnerForActivity");
8612         synchronized(this) {
8613             ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
8614             if (r == null) {
8615                 throw new IllegalArgumentException("Activity does not exist; token="
8616                         + activityToken);
8617             }
8618             return r.getUriPermissionsLocked().getExternalTokenLocked();
8619         }
8620     }
8621     /**
8622      * @param uri This uri must NOT contain an embedded userId.
8623      * @param sourceUserId The userId in which the uri is to be resolved.
8624      * @param targetUserId The userId of the app that receives the grant.
8625      */
8626     @Override
8627     public void grantUriPermissionFromOwner(IBinder token, int fromUid, String targetPkg, Uri uri,
8628             final int modeFlags, int sourceUserId, int targetUserId) {
8629         targetUserId = mUserController.handleIncomingUser(Binder.getCallingPid(),
8630                 Binder.getCallingUid(), targetUserId, false, ALLOW_FULL_ONLY,
8631                 "grantUriPermissionFromOwner", null);
8632         synchronized(this) {
8633             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8634             if (owner == null) {
8635                 throw new IllegalArgumentException("Unknown owner: " + token);
8636             }
8637             if (fromUid != Binder.getCallingUid()) {
8638                 if (Binder.getCallingUid() != Process.myUid()) {
8639                     // Only system code can grant URI permissions on behalf
8640                     // of other users.
8641                     throw new SecurityException("nice try");
8642                 }
8643             }
8644             if (targetPkg == null) {
8645                 throw new IllegalArgumentException("null target");
8646             }
8647             if (uri == null) {
8648                 throw new IllegalArgumentException("null uri");
8649             }
8650
8651             grantUriPermissionLocked(fromUid, targetPkg, new GrantUri(sourceUserId, uri, false),
8652                     modeFlags, owner, targetUserId);
8653         }
8654     }
8655
8656     /**
8657      * @param uri This uri must NOT contain an embedded userId.
8658      * @param userId The userId in which the uri is to be resolved.
8659      */
8660     @Override
8661     public void revokeUriPermissionFromOwner(IBinder token, Uri uri, int mode, int userId) {
8662         synchronized(this) {
8663             UriPermissionOwner owner = UriPermissionOwner.fromExternalToken(token);
8664             if (owner == null) {
8665                 throw new IllegalArgumentException("Unknown owner: " + token);
8666             }
8667
8668             if (uri == null) {
8669                 owner.removeUriPermissionsLocked(mode);
8670             } else {
8671                 final boolean prefix = (mode & Intent.FLAG_GRANT_PREFIX_URI_PERMISSION) != 0;
8672                 owner.removeUriPermissionLocked(new GrantUri(userId, uri, prefix), mode);
8673             }
8674         }
8675     }
8676
8677     private void schedulePersistUriGrants() {
8678         if (!mHandler.hasMessages(PERSIST_URI_GRANTS_MSG)) {
8679             mHandler.sendMessageDelayed(mHandler.obtainMessage(PERSIST_URI_GRANTS_MSG),
8680                     10 * DateUtils.SECOND_IN_MILLIS);
8681         }
8682     }
8683
8684     private void writeGrantedUriPermissions() {
8685         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "writeGrantedUriPermissions()");
8686
8687         // Snapshot permissions so we can persist without lock
8688         ArrayList<UriPermission.Snapshot> persist = Lists.newArrayList();
8689         synchronized (this) {
8690             final int size = mGrantedUriPermissions.size();
8691             for (int i = 0; i < size; i++) {
8692                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8693                 for (UriPermission perm : perms.values()) {
8694                     if (perm.persistedModeFlags != 0) {
8695                         persist.add(perm.snapshot());
8696                     }
8697                 }
8698             }
8699         }
8700
8701         FileOutputStream fos = null;
8702         try {
8703             fos = mGrantFile.startWrite();
8704
8705             XmlSerializer out = new FastXmlSerializer();
8706             out.setOutput(fos, StandardCharsets.UTF_8.name());
8707             out.startDocument(null, true);
8708             out.startTag(null, TAG_URI_GRANTS);
8709             for (UriPermission.Snapshot perm : persist) {
8710                 out.startTag(null, TAG_URI_GRANT);
8711                 writeIntAttribute(out, ATTR_SOURCE_USER_ID, perm.uri.sourceUserId);
8712                 writeIntAttribute(out, ATTR_TARGET_USER_ID, perm.targetUserId);
8713                 out.attribute(null, ATTR_SOURCE_PKG, perm.sourcePkg);
8714                 out.attribute(null, ATTR_TARGET_PKG, perm.targetPkg);
8715                 out.attribute(null, ATTR_URI, String.valueOf(perm.uri.uri));
8716                 writeBooleanAttribute(out, ATTR_PREFIX, perm.uri.prefix);
8717                 writeIntAttribute(out, ATTR_MODE_FLAGS, perm.persistedModeFlags);
8718                 writeLongAttribute(out, ATTR_CREATED_TIME, perm.persistedCreateTime);
8719                 out.endTag(null, TAG_URI_GRANT);
8720             }
8721             out.endTag(null, TAG_URI_GRANTS);
8722             out.endDocument();
8723
8724             mGrantFile.finishWrite(fos);
8725         } catch (IOException e) {
8726             if (fos != null) {
8727                 mGrantFile.failWrite(fos);
8728             }
8729         }
8730     }
8731
8732     private void readGrantedUriPermissionsLocked() {
8733         if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION, "readGrantedUriPermissions()");
8734
8735         final long now = System.currentTimeMillis();
8736
8737         FileInputStream fis = null;
8738         try {
8739             fis = mGrantFile.openRead();
8740             final XmlPullParser in = Xml.newPullParser();
8741             in.setInput(fis, StandardCharsets.UTF_8.name());
8742
8743             int type;
8744             while ((type = in.next()) != END_DOCUMENT) {
8745                 final String tag = in.getName();
8746                 if (type == START_TAG) {
8747                     if (TAG_URI_GRANT.equals(tag)) {
8748                         final int sourceUserId;
8749                         final int targetUserId;
8750                         final int userHandle = readIntAttribute(in,
8751                                 ATTR_USER_HANDLE, UserHandle.USER_NULL);
8752                         if (userHandle != UserHandle.USER_NULL) {
8753                             // For backwards compatibility.
8754                             sourceUserId = userHandle;
8755                             targetUserId = userHandle;
8756                         } else {
8757                             sourceUserId = readIntAttribute(in, ATTR_SOURCE_USER_ID);
8758                             targetUserId = readIntAttribute(in, ATTR_TARGET_USER_ID);
8759                         }
8760                         final String sourcePkg = in.getAttributeValue(null, ATTR_SOURCE_PKG);
8761                         final String targetPkg = in.getAttributeValue(null, ATTR_TARGET_PKG);
8762                         final Uri uri = Uri.parse(in.getAttributeValue(null, ATTR_URI));
8763                         final boolean prefix = readBooleanAttribute(in, ATTR_PREFIX);
8764                         final int modeFlags = readIntAttribute(in, ATTR_MODE_FLAGS);
8765                         final long createdTime = readLongAttribute(in, ATTR_CREATED_TIME, now);
8766
8767                         // Sanity check that provider still belongs to source package
8768                         // Both direct boot aware and unaware packages are fine as we
8769                         // will do filtering at query time to avoid multiple parsing.
8770                         final ProviderInfo pi = getProviderInfoLocked(
8771                                 uri.getAuthority(), sourceUserId, MATCH_DIRECT_BOOT_AWARE
8772                                         | MATCH_DIRECT_BOOT_UNAWARE);
8773                         if (pi != null && sourcePkg.equals(pi.packageName)) {
8774                             int targetUid = -1;
8775                             try {
8776                                 targetUid = AppGlobals.getPackageManager().getPackageUid(
8777                                         targetPkg, MATCH_UNINSTALLED_PACKAGES, targetUserId);
8778                             } catch (RemoteException e) {
8779                             }
8780                             if (targetUid != -1) {
8781                                 final UriPermission perm = findOrCreateUriPermissionLocked(
8782                                         sourcePkg, targetPkg, targetUid,
8783                                         new GrantUri(sourceUserId, uri, prefix));
8784                                 perm.initPersistedModes(modeFlags, createdTime);
8785                             }
8786                         } else {
8787                             Slog.w(TAG, "Persisted grant for " + uri + " had source " + sourcePkg
8788                                     + " but instead found " + pi);
8789                         }
8790                     }
8791                 }
8792             }
8793         } catch (FileNotFoundException e) {
8794             // Missing grants is okay
8795         } catch (IOException e) {
8796             Slog.wtf(TAG, "Failed reading Uri grants", e);
8797         } catch (XmlPullParserException e) {
8798             Slog.wtf(TAG, "Failed reading Uri grants", e);
8799         } finally {
8800             IoUtils.closeQuietly(fis);
8801         }
8802     }
8803
8804     /**
8805      * @param uri This uri must NOT contain an embedded userId.
8806      * @param userId The userId in which the uri is to be resolved.
8807      */
8808     @Override
8809     public void takePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8810         enforceNotIsolatedCaller("takePersistableUriPermission");
8811
8812         Preconditions.checkFlagsArgument(modeFlags,
8813                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8814
8815         synchronized (this) {
8816             final int callingUid = Binder.getCallingUid();
8817             boolean persistChanged = false;
8818             GrantUri grantUri = new GrantUri(userId, uri, false);
8819
8820             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8821                     new GrantUri(userId, uri, false));
8822             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8823                     new GrantUri(userId, uri, true));
8824
8825             final boolean exactValid = (exactPerm != null)
8826                     && ((modeFlags & exactPerm.persistableModeFlags) == modeFlags);
8827             final boolean prefixValid = (prefixPerm != null)
8828                     && ((modeFlags & prefixPerm.persistableModeFlags) == modeFlags);
8829
8830             if (!(exactValid || prefixValid)) {
8831                 throw new SecurityException("No persistable permission grants found for UID "
8832                         + callingUid + " and Uri " + grantUri.toSafeString());
8833             }
8834
8835             if (exactValid) {
8836                 persistChanged |= exactPerm.takePersistableModes(modeFlags);
8837             }
8838             if (prefixValid) {
8839                 persistChanged |= prefixPerm.takePersistableModes(modeFlags);
8840             }
8841
8842             persistChanged |= maybePrunePersistedUriGrantsLocked(callingUid);
8843
8844             if (persistChanged) {
8845                 schedulePersistUriGrants();
8846             }
8847         }
8848     }
8849
8850     /**
8851      * @param uri This uri must NOT contain an embedded userId.
8852      * @param userId The userId in which the uri is to be resolved.
8853      */
8854     @Override
8855     public void releasePersistableUriPermission(Uri uri, final int modeFlags, int userId) {
8856         enforceNotIsolatedCaller("releasePersistableUriPermission");
8857
8858         Preconditions.checkFlagsArgument(modeFlags,
8859                 Intent.FLAG_GRANT_READ_URI_PERMISSION | Intent.FLAG_GRANT_WRITE_URI_PERMISSION);
8860
8861         synchronized (this) {
8862             final int callingUid = Binder.getCallingUid();
8863             boolean persistChanged = false;
8864
8865             UriPermission exactPerm = findUriPermissionLocked(callingUid,
8866                     new GrantUri(userId, uri, false));
8867             UriPermission prefixPerm = findUriPermissionLocked(callingUid,
8868                     new GrantUri(userId, uri, true));
8869             if (exactPerm == null && prefixPerm == null) {
8870                 throw new SecurityException("No permission grants found for UID " + callingUid
8871                         + " and Uri " + uri.toSafeString());
8872             }
8873
8874             if (exactPerm != null) {
8875                 persistChanged |= exactPerm.releasePersistableModes(modeFlags);
8876                 removeUriPermissionIfNeededLocked(exactPerm);
8877             }
8878             if (prefixPerm != null) {
8879                 persistChanged |= prefixPerm.releasePersistableModes(modeFlags);
8880                 removeUriPermissionIfNeededLocked(prefixPerm);
8881             }
8882
8883             if (persistChanged) {
8884                 schedulePersistUriGrants();
8885             }
8886         }
8887     }
8888
8889     /**
8890      * Prune any older {@link UriPermission} for the given UID until outstanding
8891      * persisted grants are below {@link #MAX_PERSISTED_URI_GRANTS}.
8892      *
8893      * @return if any mutations occured that require persisting.
8894      */
8895     private boolean maybePrunePersistedUriGrantsLocked(int uid) {
8896         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(uid);
8897         if (perms == null) return false;
8898         if (perms.size() < MAX_PERSISTED_URI_GRANTS) return false;
8899
8900         final ArrayList<UriPermission> persisted = Lists.newArrayList();
8901         for (UriPermission perm : perms.values()) {
8902             if (perm.persistedModeFlags != 0) {
8903                 persisted.add(perm);
8904             }
8905         }
8906
8907         final int trimCount = persisted.size() - MAX_PERSISTED_URI_GRANTS;
8908         if (trimCount <= 0) return false;
8909
8910         Collections.sort(persisted, new UriPermission.PersistedTimeComparator());
8911         for (int i = 0; i < trimCount; i++) {
8912             final UriPermission perm = persisted.get(i);
8913
8914             if (DEBUG_URI_PERMISSION) Slog.v(TAG_URI_PERMISSION,
8915                     "Trimming grant created at " + perm.persistedCreateTime);
8916
8917             perm.releasePersistableModes(~0);
8918             removeUriPermissionIfNeededLocked(perm);
8919         }
8920
8921         return true;
8922     }
8923
8924     @Override
8925     public ParceledListSlice<android.content.UriPermission> getPersistedUriPermissions(
8926             String packageName, boolean incoming) {
8927         enforceNotIsolatedCaller("getPersistedUriPermissions");
8928         Preconditions.checkNotNull(packageName, "packageName");
8929
8930         final int callingUid = Binder.getCallingUid();
8931         final int callingUserId = UserHandle.getUserId(callingUid);
8932         final IPackageManager pm = AppGlobals.getPackageManager();
8933         try {
8934             final int packageUid = pm.getPackageUid(packageName,
8935                     MATCH_DIRECT_BOOT_AWARE | MATCH_DIRECT_BOOT_UNAWARE, callingUserId);
8936             if (packageUid != callingUid) {
8937                 throw new SecurityException(
8938                         "Package " + packageName + " does not belong to calling UID " + callingUid);
8939             }
8940         } catch (RemoteException e) {
8941             throw new SecurityException("Failed to verify package name ownership");
8942         }
8943
8944         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8945         synchronized (this) {
8946             if (incoming) {
8947                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(
8948                         callingUid);
8949                 if (perms == null) {
8950                     Slog.w(TAG, "No permission grants found for " + packageName);
8951                 } else {
8952                     for (UriPermission perm : perms.values()) {
8953                         if (packageName.equals(perm.targetPkg) && perm.persistedModeFlags != 0) {
8954                             result.add(perm.buildPersistedPublicApiObject());
8955                         }
8956                     }
8957                 }
8958             } else {
8959                 final int size = mGrantedUriPermissions.size();
8960                 for (int i = 0; i < size; i++) {
8961                     final ArrayMap<GrantUri, UriPermission> perms =
8962                             mGrantedUriPermissions.valueAt(i);
8963                     for (UriPermission perm : perms.values()) {
8964                         if (packageName.equals(perm.sourcePkg) && perm.persistedModeFlags != 0) {
8965                             result.add(perm.buildPersistedPublicApiObject());
8966                         }
8967                     }
8968                 }
8969             }
8970         }
8971         return new ParceledListSlice<android.content.UriPermission>(result);
8972     }
8973
8974     @Override
8975     public ParceledListSlice<android.content.UriPermission> getGrantedUriPermissions(
8976             String packageName, int userId) {
8977         enforceCallingPermission(android.Manifest.permission.GET_APP_GRANTED_URI_PERMISSIONS,
8978                 "getGrantedUriPermissions");
8979
8980         final ArrayList<android.content.UriPermission> result = Lists.newArrayList();
8981         synchronized (this) {
8982             final int size = mGrantedUriPermissions.size();
8983             for (int i = 0; i < size; i++) {
8984                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
8985                 for (UriPermission perm : perms.values()) {
8986                     if (packageName.equals(perm.targetPkg) && perm.targetUserId == userId
8987                             && perm.persistedModeFlags != 0) {
8988                         result.add(perm.buildPersistedPublicApiObject());
8989                     }
8990                 }
8991             }
8992         }
8993         return new ParceledListSlice<android.content.UriPermission>(result);
8994     }
8995
8996     @Override
8997     public void clearGrantedUriPermissions(String packageName, int userId) {
8998         enforceCallingPermission(android.Manifest.permission.CLEAR_APP_GRANTED_URI_PERMISSIONS,
8999                 "clearGrantedUriPermissions");
9000         removeUriPermissionsForPackageLocked(packageName, userId, true);
9001     }
9002
9003     @Override
9004     public void showWaitingForDebugger(IApplicationThread who, boolean waiting) {
9005         synchronized (this) {
9006             ProcessRecord app =
9007                 who != null ? getRecordForAppLocked(who) : null;
9008             if (app == null) return;
9009
9010             Message msg = Message.obtain();
9011             msg.what = WAIT_FOR_DEBUGGER_UI_MSG;
9012             msg.obj = app;
9013             msg.arg1 = waiting ? 1 : 0;
9014             mUiHandler.sendMessage(msg);
9015         }
9016     }
9017
9018     @Override
9019     public void getMemoryInfo(ActivityManager.MemoryInfo outInfo) {
9020         final long homeAppMem = mProcessList.getMemLevel(ProcessList.HOME_APP_ADJ);
9021         final long cachedAppMem = mProcessList.getMemLevel(ProcessList.CACHED_APP_MIN_ADJ);
9022         outInfo.availMem = Process.getFreeMemory();
9023         outInfo.totalMem = Process.getTotalMemory();
9024         outInfo.threshold = homeAppMem;
9025         outInfo.lowMemory = outInfo.availMem < (homeAppMem + ((cachedAppMem-homeAppMem)/2));
9026         outInfo.hiddenAppThreshold = cachedAppMem;
9027         outInfo.secondaryServerThreshold = mProcessList.getMemLevel(
9028                 ProcessList.SERVICE_ADJ);
9029         outInfo.visibleAppThreshold = mProcessList.getMemLevel(
9030                 ProcessList.VISIBLE_APP_ADJ);
9031         outInfo.foregroundAppThreshold = mProcessList.getMemLevel(
9032                 ProcessList.FOREGROUND_APP_ADJ);
9033     }
9034
9035     // =========================================================
9036     // TASK MANAGEMENT
9037     // =========================================================
9038
9039     @Override
9040     public List<IAppTask> getAppTasks(String callingPackage) {
9041         int callingUid = Binder.getCallingUid();
9042         long ident = Binder.clearCallingIdentity();
9043
9044         synchronized(this) {
9045             ArrayList<IAppTask> list = new ArrayList<IAppTask>();
9046             try {
9047                 if (DEBUG_ALL) Slog.v(TAG, "getAppTasks");
9048
9049                 final int N = mRecentTasks.size();
9050                 for (int i = 0; i < N; i++) {
9051                     TaskRecord tr = mRecentTasks.get(i);
9052                     // Skip tasks that do not match the caller.  We don't need to verify
9053                     // callingPackage, because we are also limiting to callingUid and know
9054                     // that will limit to the correct security sandbox.
9055                     if (tr.effectiveUid != callingUid) {
9056                         continue;
9057                     }
9058                     Intent intent = tr.getBaseIntent();
9059                     if (intent == null ||
9060                             !callingPackage.equals(intent.getComponent().getPackageName())) {
9061                         continue;
9062                     }
9063                     ActivityManager.RecentTaskInfo taskInfo =
9064                             createRecentTaskInfoFromTaskRecord(tr);
9065                     AppTaskImpl taskImpl = new AppTaskImpl(taskInfo.persistentId, callingUid);
9066                     list.add(taskImpl);
9067                 }
9068             } finally {
9069                 Binder.restoreCallingIdentity(ident);
9070             }
9071             return list;
9072         }
9073     }
9074
9075     @Override
9076     public List<RunningTaskInfo> getTasks(int maxNum, int flags) {
9077         final int callingUid = Binder.getCallingUid();
9078         ArrayList<RunningTaskInfo> list = new ArrayList<RunningTaskInfo>();
9079
9080         synchronized(this) {
9081             if (DEBUG_ALL) Slog.v(
9082                 TAG, "getTasks: max=" + maxNum + ", flags=" + flags);
9083
9084             final boolean allowed = isGetTasksAllowed("getTasks", Binder.getCallingPid(),
9085                     callingUid);
9086
9087             // TODO: Improve with MRU list from all ActivityStacks.
9088             mStackSupervisor.getTasksLocked(maxNum, list, callingUid, allowed);
9089         }
9090
9091         return list;
9092     }
9093
9094     /**
9095      * Creates a new RecentTaskInfo from a TaskRecord.
9096      */
9097     private ActivityManager.RecentTaskInfo createRecentTaskInfoFromTaskRecord(TaskRecord tr) {
9098         // Update the task description to reflect any changes in the task stack
9099         tr.updateTaskDescription();
9100
9101         // Compose the recent task info
9102         ActivityManager.RecentTaskInfo rti = new ActivityManager.RecentTaskInfo();
9103         rti.id = tr.getTopActivity() == null ? INVALID_TASK_ID : tr.taskId;
9104         rti.persistentId = tr.taskId;
9105         rti.baseIntent = new Intent(tr.getBaseIntent());
9106         rti.origActivity = tr.origActivity;
9107         rti.realActivity = tr.realActivity;
9108         rti.description = tr.lastDescription;
9109         rti.stackId = tr.stack != null ? tr.stack.mStackId : -1;
9110         rti.userId = tr.userId;
9111         rti.taskDescription = new ActivityManager.TaskDescription(tr.lastTaskDescription);
9112         rti.firstActiveTime = tr.firstActiveTime;
9113         rti.lastActiveTime = tr.lastActiveTime;
9114         rti.affiliatedTaskId = tr.mAffiliatedTaskId;
9115         rti.affiliatedTaskColor = tr.mAffiliatedTaskColor;
9116         rti.numActivities = 0;
9117         if (tr.mBounds != null) {
9118             rti.bounds = new Rect(tr.mBounds);
9119         }
9120         rti.isDockable = tr.canGoInDockedStack();
9121         rti.resizeMode = tr.mResizeMode;
9122
9123         ActivityRecord base = null;
9124         ActivityRecord top = null;
9125         ActivityRecord tmp;
9126
9127         for (int i = tr.mActivities.size() - 1; i >= 0; --i) {
9128             tmp = tr.mActivities.get(i);
9129             if (tmp.finishing) {
9130                 continue;
9131             }
9132             base = tmp;
9133             if (top == null || (top.state == ActivityState.INITIALIZING)) {
9134                 top = base;
9135             }
9136             rti.numActivities++;
9137         }
9138
9139         rti.baseActivity = (base != null) ? base.intent.getComponent() : null;
9140         rti.topActivity = (top != null) ? top.intent.getComponent() : null;
9141
9142         return rti;
9143     }
9144
9145     private boolean isGetTasksAllowed(String caller, int callingPid, int callingUid) {
9146         boolean allowed = checkPermission(android.Manifest.permission.REAL_GET_TASKS,
9147                 callingPid, callingUid) == PackageManager.PERMISSION_GRANTED;
9148         if (!allowed) {
9149             if (checkPermission(android.Manifest.permission.GET_TASKS,
9150                     callingPid, callingUid) == PackageManager.PERMISSION_GRANTED) {
9151                 // Temporary compatibility: some existing apps on the system image may
9152                 // still be requesting the old permission and not switched to the new
9153                 // one; if so, we'll still allow them full access.  This means we need
9154                 // to see if they are holding the old permission and are a system app.
9155                 try {
9156                     if (AppGlobals.getPackageManager().isUidPrivileged(callingUid)) {
9157                         allowed = true;
9158                         if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9159                                 + " is using old GET_TASKS but privileged; allowing");
9160                     }
9161                 } catch (RemoteException e) {
9162                 }
9163             }
9164         }
9165         if (!allowed) {
9166             if (DEBUG_TASKS) Slog.w(TAG, caller + ": caller " + callingUid
9167                     + " does not hold REAL_GET_TASKS; limiting output");
9168         }
9169         return allowed;
9170     }
9171
9172     @Override
9173     public ParceledListSlice<ActivityManager.RecentTaskInfo> getRecentTasks(int maxNum, int flags,
9174             int userId) {
9175         final int callingUid = Binder.getCallingUid();
9176         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), callingUid, userId,
9177                 false, ALLOW_FULL_ONLY, "getRecentTasks", null);
9178
9179         final boolean includeProfiles = (flags & ActivityManager.RECENT_INCLUDE_PROFILES) != 0;
9180         final boolean withExcluded = (flags&ActivityManager.RECENT_WITH_EXCLUDED) != 0;
9181         synchronized (this) {
9182             final boolean allowed = isGetTasksAllowed("getRecentTasks", Binder.getCallingPid(),
9183                     callingUid);
9184             final boolean detailed = checkCallingPermission(
9185                     android.Manifest.permission.GET_DETAILED_TASKS)
9186                     == PackageManager.PERMISSION_GRANTED;
9187
9188             if (!isUserRunning(userId, ActivityManager.FLAG_AND_UNLOCKED)) {
9189                 Slog.i(TAG, "user " + userId + " is still locked. Cannot load recents");
9190                 return ParceledListSlice.emptyList();
9191             }
9192             mRecentTasks.loadUserRecentsLocked(userId);
9193
9194             final int recentsCount = mRecentTasks.size();
9195             ArrayList<ActivityManager.RecentTaskInfo> res =
9196                     new ArrayList<>(maxNum < recentsCount ? maxNum : recentsCount);
9197
9198             final Set<Integer> includedUsers;
9199             if (includeProfiles) {
9200                 includedUsers = mUserController.getProfileIds(userId);
9201             } else {
9202                 includedUsers = new HashSet<>();
9203             }
9204             includedUsers.add(Integer.valueOf(userId));
9205
9206             for (int i = 0; i < recentsCount && maxNum > 0; i++) {
9207                 TaskRecord tr = mRecentTasks.get(i);
9208                 // Only add calling user or related users recent tasks
9209                 if (!includedUsers.contains(Integer.valueOf(tr.userId))) {
9210                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not user: " + tr);
9211                     continue;
9212                 }
9213
9214                 if (tr.realActivitySuspended) {
9215                     if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, activity suspended: " + tr);
9216                     continue;
9217                 }
9218
9219                 // Return the entry if desired by the caller.  We always return
9220                 // the first entry, because callers always expect this to be the
9221                 // foreground app.  We may filter others if the caller has
9222                 // not supplied RECENT_WITH_EXCLUDED and there is some reason
9223                 // we should exclude the entry.
9224
9225                 if (i == 0
9226                         || withExcluded
9227                         || (tr.intent == null)
9228                         || ((tr.intent.getFlags() & Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS)
9229                                 == 0)) {
9230                     if (!allowed) {
9231                         // If the caller doesn't have the GET_TASKS permission, then only
9232                         // allow them to see a small subset of tasks -- their own and home.
9233                         if (!tr.isHomeTask() && tr.effectiveUid != callingUid) {
9234                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS, "Skipping, not allowed: " + tr);
9235                             continue;
9236                         }
9237                     }
9238                     if ((flags & ActivityManager.RECENT_IGNORE_HOME_STACK_TASKS) != 0) {
9239                         if (tr.stack != null && tr.stack.isHomeStack()) {
9240                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9241                                     "Skipping, home stack task: " + tr);
9242                             continue;
9243                         }
9244                     }
9245                     if ((flags & ActivityManager.RECENT_INGORE_DOCKED_STACK_TOP_TASK) != 0) {
9246                         final ActivityStack stack = tr.stack;
9247                         if (stack != null && stack.isDockedStack() && stack.topTask() == tr) {
9248                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9249                                     "Skipping, top task in docked stack: " + tr);
9250                             continue;
9251                         }
9252                     }
9253                     if ((flags & ActivityManager.RECENT_INGORE_PINNED_STACK_TASKS) != 0) {
9254                         if (tr.stack != null && tr.stack.isPinnedStack()) {
9255                             if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9256                                     "Skipping, pinned stack task: " + tr);
9257                             continue;
9258                         }
9259                     }
9260                     if (tr.autoRemoveRecents && tr.getTopActivity() == null) {
9261                         // Don't include auto remove tasks that are finished or finishing.
9262                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9263                                 "Skipping, auto-remove without activity: " + tr);
9264                         continue;
9265                     }
9266                     if ((flags&ActivityManager.RECENT_IGNORE_UNAVAILABLE) != 0
9267                             && !tr.isAvailable) {
9268                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9269                                 "Skipping, unavail real act: " + tr);
9270                         continue;
9271                     }
9272
9273                     if (!tr.mUserSetupComplete) {
9274                         // Don't include task launched while user is not done setting-up.
9275                         if (DEBUG_RECENTS) Slog.d(TAG_RECENTS,
9276                                 "Skipping, user setup not complete: " + tr);
9277                         continue;
9278                     }
9279
9280                     ActivityManager.RecentTaskInfo rti = createRecentTaskInfoFromTaskRecord(tr);
9281                     if (!detailed) {
9282                         rti.baseIntent.replaceExtras((Bundle)null);
9283                     }
9284
9285                     res.add(rti);
9286                     maxNum--;
9287                 }
9288             }
9289             return new ParceledListSlice<>(res);
9290         }
9291     }
9292
9293     @Override
9294     public ActivityManager.TaskThumbnail getTaskThumbnail(int id) {
9295         synchronized (this) {
9296             enforceCallingPermission(android.Manifest.permission.READ_FRAME_BUFFER,
9297                     "getTaskThumbnail()");
9298             final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9299                     id, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9300             if (tr != null) {
9301                 return tr.getTaskThumbnailLocked();
9302             }
9303         }
9304         return null;
9305     }
9306
9307     @Override
9308     public int addAppTask(IBinder activityToken, Intent intent,
9309             ActivityManager.TaskDescription description, Bitmap thumbnail) throws RemoteException {
9310         final int callingUid = Binder.getCallingUid();
9311         final long callingIdent = Binder.clearCallingIdentity();
9312
9313         try {
9314             synchronized (this) {
9315                 ActivityRecord r = ActivityRecord.isInStackLocked(activityToken);
9316                 if (r == null) {
9317                     throw new IllegalArgumentException("Activity does not exist; token="
9318                             + activityToken);
9319                 }
9320                 ComponentName comp = intent.getComponent();
9321                 if (comp == null) {
9322                     throw new IllegalArgumentException("Intent " + intent
9323                             + " must specify explicit component");
9324                 }
9325                 if (thumbnail.getWidth() != mThumbnailWidth
9326                         || thumbnail.getHeight() != mThumbnailHeight) {
9327                     throw new IllegalArgumentException("Bad thumbnail size: got "
9328                             + thumbnail.getWidth() + "x" + thumbnail.getHeight() + ", require "
9329                             + mThumbnailWidth + "x" + mThumbnailHeight);
9330                 }
9331                 if (intent.getSelector() != null) {
9332                     intent.setSelector(null);
9333                 }
9334                 if (intent.getSourceBounds() != null) {
9335                     intent.setSourceBounds(null);
9336                 }
9337                 if ((intent.getFlags()&Intent.FLAG_ACTIVITY_NEW_DOCUMENT) != 0) {
9338                     if ((intent.getFlags()&Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS) == 0) {
9339                         // The caller has added this as an auto-remove task...  that makes no
9340                         // sense, so turn off auto-remove.
9341                         intent.addFlags(Intent.FLAG_ACTIVITY_RETAIN_IN_RECENTS);
9342                     }
9343                 }
9344                 if (!comp.equals(mLastAddedTaskComponent) || callingUid != mLastAddedTaskUid) {
9345                     mLastAddedTaskActivity = null;
9346                 }
9347                 ActivityInfo ainfo = mLastAddedTaskActivity;
9348                 if (ainfo == null) {
9349                     ainfo = mLastAddedTaskActivity = AppGlobals.getPackageManager().getActivityInfo(
9350                             comp, 0, UserHandle.getUserId(callingUid));
9351                     if (ainfo.applicationInfo.uid != callingUid) {
9352                         throw new SecurityException(
9353                                 "Can't add task for another application: target uid="
9354                                 + ainfo.applicationInfo.uid + ", calling uid=" + callingUid);
9355                     }
9356                 }
9357
9358                 // Use the full screen as the context for the task thumbnail
9359                 final Point displaySize = new Point();
9360                 final TaskThumbnailInfo thumbnailInfo = new TaskThumbnailInfo();
9361                 r.task.stack.getDisplaySize(displaySize);
9362                 thumbnailInfo.taskWidth = displaySize.x;
9363                 thumbnailInfo.taskHeight = displaySize.y;
9364                 thumbnailInfo.screenOrientation = mConfiguration.orientation;
9365
9366                 TaskRecord task = new TaskRecord(this,
9367                         mStackSupervisor.getNextTaskIdForUserLocked(r.userId),
9368                         ainfo, intent, description, thumbnailInfo);
9369
9370                 int trimIdx = mRecentTasks.trimForTaskLocked(task, false);
9371                 if (trimIdx >= 0) {
9372                     // If this would have caused a trim, then we'll abort because that
9373                     // means it would be added at the end of the list but then just removed.
9374                     return INVALID_TASK_ID;
9375                 }
9376
9377                 final int N = mRecentTasks.size();
9378                 if (N >= (ActivityManager.getMaxRecentTasksStatic()-1)) {
9379                     final TaskRecord tr = mRecentTasks.remove(N - 1);
9380                     tr.removedFromRecents();
9381                 }
9382
9383                 task.inRecents = true;
9384                 mRecentTasks.add(task);
9385                 r.task.stack.addTask(task, false, "addAppTask");
9386
9387                 task.setLastThumbnailLocked(thumbnail);
9388                 task.freeLastThumbnail();
9389
9390                 return task.taskId;
9391             }
9392         } finally {
9393             Binder.restoreCallingIdentity(callingIdent);
9394         }
9395     }
9396
9397     @Override
9398     public Point getAppTaskThumbnailSize() {
9399         synchronized (this) {
9400             return new Point(mThumbnailWidth,  mThumbnailHeight);
9401         }
9402     }
9403
9404     @Override
9405     public void setTaskDescription(IBinder token, ActivityManager.TaskDescription td) {
9406         synchronized (this) {
9407             ActivityRecord r = ActivityRecord.isInStackLocked(token);
9408             if (r != null) {
9409                 r.setTaskDescription(td);
9410                 r.task.updateTaskDescription();
9411             }
9412         }
9413     }
9414
9415     @Override
9416     public void setTaskResizeable(int taskId, int resizeableMode) {
9417         synchronized (this) {
9418             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9419                     taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9420             if (task == null) {
9421                 Slog.w(TAG, "setTaskResizeable: taskId=" + taskId + " not found");
9422                 return;
9423             }
9424             if (task.mResizeMode != resizeableMode) {
9425                 task.mResizeMode = resizeableMode;
9426                 mWindowManager.setTaskResizeable(taskId, resizeableMode);
9427                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9428                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9429             }
9430         }
9431     }
9432
9433     @Override
9434     public void resizeTask(int taskId, Rect bounds, int resizeMode) {
9435         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeTask()");
9436         long ident = Binder.clearCallingIdentity();
9437         try {
9438             synchronized (this) {
9439                 TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9440                 if (task == null) {
9441                     Slog.w(TAG, "resizeTask: taskId=" + taskId + " not found");
9442                     return;
9443                 }
9444                 int stackId = task.stack.mStackId;
9445                 // We allow the task to scroll instead of resizing if this is a non-resizeable task
9446                 // in crop windows resize mode or if the task size is affected by the docked stack
9447                 // changing size. No need to update configuration.
9448                 if (bounds != null && task.inCropWindowsResizeMode()
9449                         && mStackSupervisor.isStackDockedInEffect(stackId)) {
9450                     mWindowManager.scrollTask(task.taskId, bounds);
9451                     return;
9452                 }
9453
9454                 // Place the task in the right stack if it isn't there already based on
9455                 // the requested bounds.
9456                 // The stack transition logic is:
9457                 // - a null bounds on a freeform task moves that task to fullscreen
9458                 // - a non-null bounds on a non-freeform (fullscreen OR docked) task moves
9459                 //   that task to freeform
9460                 // - otherwise the task is not moved
9461                 if (!StackId.isTaskResizeAllowed(stackId)) {
9462                     throw new IllegalArgumentException("resizeTask not allowed on task=" + task);
9463                 }
9464                 if (bounds == null && stackId == FREEFORM_WORKSPACE_STACK_ID) {
9465                     stackId = FULLSCREEN_WORKSPACE_STACK_ID;
9466                 } else if (bounds != null && stackId != FREEFORM_WORKSPACE_STACK_ID ) {
9467                     stackId = FREEFORM_WORKSPACE_STACK_ID;
9468                 }
9469                 boolean preserveWindow = (resizeMode & RESIZE_MODE_PRESERVE_WINDOW) != 0;
9470                 if (stackId != task.stack.mStackId) {
9471                     mStackSupervisor.moveTaskToStackUncheckedLocked(
9472                             task, stackId, ON_TOP, !FORCE_FOCUS, "resizeTask");
9473                     preserveWindow = false;
9474                 }
9475
9476                 mStackSupervisor.resizeTaskLocked(task, bounds, resizeMode, preserveWindow,
9477                         false /* deferResume */);
9478             }
9479         } finally {
9480             Binder.restoreCallingIdentity(ident);
9481         }
9482     }
9483
9484     @Override
9485     public Rect getTaskBounds(int taskId) {
9486         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getTaskBounds()");
9487         long ident = Binder.clearCallingIdentity();
9488         Rect rect = new Rect();
9489         try {
9490             synchronized (this) {
9491                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(
9492                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9493                 if (task == null) {
9494                     Slog.w(TAG, "getTaskBounds: taskId=" + taskId + " not found");
9495                     return rect;
9496                 }
9497                 if (task.stack != null) {
9498                     // Return the bounds from window manager since it will be adjusted for various
9499                     // things like the presense of a docked stack for tasks that aren't resizeable.
9500                     mWindowManager.getTaskBounds(task.taskId, rect);
9501                 } else {
9502                     // Task isn't in window manager yet since it isn't associated with a stack.
9503                     // Return the persist value from activity manager
9504                     if (task.mBounds != null) {
9505                         rect.set(task.mBounds);
9506                     } else if (task.mLastNonFullscreenBounds != null) {
9507                         rect.set(task.mLastNonFullscreenBounds);
9508                     }
9509                 }
9510             }
9511         } finally {
9512             Binder.restoreCallingIdentity(ident);
9513         }
9514         return rect;
9515     }
9516
9517     @Override
9518     public Bitmap getTaskDescriptionIcon(String filePath, int userId) {
9519         if (userId != UserHandle.getCallingUserId()) {
9520             enforceCallingPermission(android.Manifest.permission.INTERACT_ACROSS_USERS_FULL,
9521                     "getTaskDescriptionIcon");
9522         }
9523         final File passedIconFile = new File(filePath);
9524         final File legitIconFile = new File(TaskPersister.getUserImagesDir(userId),
9525                 passedIconFile.getName());
9526         if (!legitIconFile.getPath().equals(filePath)
9527                 || !filePath.contains(ActivityRecord.ACTIVITY_ICON_SUFFIX)) {
9528             throw new IllegalArgumentException("Bad file path: " + filePath
9529                     + " passed for userId " + userId);
9530         }
9531         return mRecentTasks.getTaskDescriptionIcon(filePath);
9532     }
9533
9534     @Override
9535     public void startInPlaceAnimationOnFrontMostApplication(ActivityOptions opts)
9536             throws RemoteException {
9537         if (opts.getAnimationType() != ActivityOptions.ANIM_CUSTOM_IN_PLACE ||
9538                 opts.getCustomInPlaceResId() == 0) {
9539             throw new IllegalArgumentException("Expected in-place ActivityOption " +
9540                     "with valid animation");
9541         }
9542         mWindowManager.prepareAppTransition(TRANSIT_TASK_IN_PLACE, false);
9543         mWindowManager.overridePendingAppTransitionInPlace(opts.getPackageName(),
9544                 opts.getCustomInPlaceResId());
9545         mWindowManager.executeAppTransition();
9546     }
9547
9548     private void cleanUpRemovedTaskLocked(TaskRecord tr, boolean killProcess,
9549             boolean removeFromRecents) {
9550         if (removeFromRecents) {
9551             mRecentTasks.remove(tr);
9552             tr.removedFromRecents();
9553         }
9554         ComponentName component = tr.getBaseIntent().getComponent();
9555         if (component == null) {
9556             Slog.w(TAG, "No component for base intent of task: " + tr);
9557             return;
9558         }
9559
9560         // Find any running services associated with this app and stop if needed.
9561         mServices.cleanUpRemovedTaskLocked(tr, component, new Intent(tr.getBaseIntent()));
9562
9563         if (!killProcess) {
9564             return;
9565         }
9566
9567         // Determine if the process(es) for this task should be killed.
9568         final String pkg = component.getPackageName();
9569         ArrayList<ProcessRecord> procsToKill = new ArrayList<>();
9570         ArrayMap<String, SparseArray<ProcessRecord>> pmap = mProcessNames.getMap();
9571         for (int i = 0; i < pmap.size(); i++) {
9572
9573             SparseArray<ProcessRecord> uids = pmap.valueAt(i);
9574             for (int j = 0; j < uids.size(); j++) {
9575                 ProcessRecord proc = uids.valueAt(j);
9576                 if (proc.userId != tr.userId) {
9577                     // Don't kill process for a different user.
9578                     continue;
9579                 }
9580                 if (proc == mHomeProcess) {
9581                     // Don't kill the home process along with tasks from the same package.
9582                     continue;
9583                 }
9584                 if (!proc.pkgList.containsKey(pkg)) {
9585                     // Don't kill process that is not associated with this task.
9586                     continue;
9587                 }
9588
9589                 for (int k = 0; k < proc.activities.size(); k++) {
9590                     TaskRecord otherTask = proc.activities.get(k).task;
9591                     if (tr.taskId != otherTask.taskId && otherTask.inRecents) {
9592                         // Don't kill process(es) that has an activity in a different task that is
9593                         // also in recents.
9594                         return;
9595                     }
9596                 }
9597
9598                 if (proc.foregroundServices) {
9599                     // Don't kill process(es) with foreground service.
9600                     return;
9601                 }
9602
9603                 // Add process to kill list.
9604                 procsToKill.add(proc);
9605             }
9606         }
9607
9608         // Kill the running processes.
9609         for (int i = 0; i < procsToKill.size(); i++) {
9610             ProcessRecord pr = procsToKill.get(i);
9611             if (pr.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND
9612                     && pr.curReceiver == null) {
9613                 pr.kill("remove task", true);
9614             } else {
9615                 // We delay killing processes that are not in the background or running a receiver.
9616                 pr.waitingToKill = "remove task";
9617             }
9618         }
9619     }
9620
9621     private void removeTasksByPackageNameLocked(String packageName, int userId) {
9622         // Remove all tasks with activities in the specified package from the list of recent tasks
9623         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9624             TaskRecord tr = mRecentTasks.get(i);
9625             if (tr.userId != userId) continue;
9626
9627             ComponentName cn = tr.intent.getComponent();
9628             if (cn != null && cn.getPackageName().equals(packageName)) {
9629                 // If the package name matches, remove the task.
9630                 removeTaskByIdLocked(tr.taskId, true, REMOVE_FROM_RECENTS);
9631             }
9632         }
9633     }
9634
9635     private void cleanupDisabledPackageTasksLocked(String packageName, Set<String> filterByClasses,
9636             int userId) {
9637
9638         for (int i = mRecentTasks.size() - 1; i >= 0; i--) {
9639             TaskRecord tr = mRecentTasks.get(i);
9640             if (userId != UserHandle.USER_ALL && tr.userId != userId) {
9641                 continue;
9642             }
9643
9644             ComponentName cn = tr.intent.getComponent();
9645             final boolean sameComponent = cn != null && cn.getPackageName().equals(packageName)
9646                     && (filterByClasses == null || filterByClasses.contains(cn.getClassName()));
9647             if (sameComponent) {
9648                 removeTaskByIdLocked(tr.taskId, false, REMOVE_FROM_RECENTS);
9649             }
9650         }
9651     }
9652
9653     /**
9654      * Removes the task with the specified task id.
9655      *
9656      * @param taskId Identifier of the task to be removed.
9657      * @param killProcess Kill any process associated with the task if possible.
9658      * @param removeFromRecents Whether to also remove the task from recents.
9659      * @return Returns true if the given task was found and removed.
9660      */
9661     private boolean removeTaskByIdLocked(int taskId, boolean killProcess,
9662             boolean removeFromRecents) {
9663         final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
9664                 taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
9665         if (tr != null) {
9666             tr.removeTaskActivitiesLocked();
9667             cleanUpRemovedTaskLocked(tr, killProcess, removeFromRecents);
9668             if (tr.isPersistable) {
9669                 notifyTaskPersisterLocked(null, true);
9670             }
9671             return true;
9672         }
9673         Slog.w(TAG, "Request to remove task ignored for non-existent task " + taskId);
9674         return false;
9675     }
9676
9677     @Override
9678     public void removeStack(int stackId) {
9679         enforceCallingPermission(Manifest.permission.MANAGE_ACTIVITY_STACKS, "removeStack()");
9680         if (stackId == HOME_STACK_ID) {
9681             throw new IllegalArgumentException("Removing home stack is not allowed.");
9682         }
9683
9684         synchronized (this) {
9685             final long ident = Binder.clearCallingIdentity();
9686             try {
9687                 final ActivityStack stack = mStackSupervisor.getStack(stackId);
9688                 if (stack == null) {
9689                     return;
9690                 }
9691                 final ArrayList<TaskRecord> tasks = stack.getAllTasks();
9692                 for (int i = tasks.size() - 1; i >= 0; i--) {
9693                     removeTaskByIdLocked(
9694                             tasks.get(i).taskId, true /* killProcess */, REMOVE_FROM_RECENTS);
9695                 }
9696             } finally {
9697                 Binder.restoreCallingIdentity(ident);
9698             }
9699         }
9700     }
9701
9702     @Override
9703     public boolean removeTask(int taskId) {
9704         enforceCallingPermission(android.Manifest.permission.REMOVE_TASKS, "removeTask()");
9705         synchronized (this) {
9706             final long ident = Binder.clearCallingIdentity();
9707             try {
9708                 return removeTaskByIdLocked(taskId, true, REMOVE_FROM_RECENTS);
9709             } finally {
9710                 Binder.restoreCallingIdentity(ident);
9711             }
9712         }
9713     }
9714
9715     /**
9716      * TODO: Add mController hook
9717      */
9718     @Override
9719     public void moveTaskToFront(int taskId, int flags, Bundle bOptions) {
9720         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS, "moveTaskToFront()");
9721
9722         if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToFront: moving taskId=" + taskId);
9723         synchronized(this) {
9724             moveTaskToFrontLocked(taskId, flags, bOptions);
9725         }
9726     }
9727
9728     void moveTaskToFrontLocked(int taskId, int flags, Bundle bOptions) {
9729         ActivityOptions options = ActivityOptions.fromBundle(bOptions);
9730
9731         if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9732                 Binder.getCallingUid(), -1, -1, "Task to front")) {
9733             ActivityOptions.abort(options);
9734             return;
9735         }
9736         final long origId = Binder.clearCallingIdentity();
9737         try {
9738             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9739             if (task == null) {
9740                 Slog.d(TAG, "Could not find task for id: "+ taskId);
9741                 return;
9742             }
9743             if (mStackSupervisor.isLockTaskModeViolation(task)) {
9744                 mStackSupervisor.showLockTaskToast();
9745                 Slog.e(TAG, "moveTaskToFront: Attempt to violate Lock Task Mode");
9746                 return;
9747             }
9748             final ActivityRecord prev = mStackSupervisor.topRunningActivityLocked();
9749             if (prev != null && prev.isRecentsActivity()) {
9750                 task.setTaskToReturnTo(ActivityRecord.RECENTS_ACTIVITY_TYPE);
9751             }
9752             mStackSupervisor.findTaskToMoveToFrontLocked(task, flags, options, "moveTaskToFront",
9753                     false /* forceNonResizable */);
9754         } finally {
9755             Binder.restoreCallingIdentity(origId);
9756         }
9757         ActivityOptions.abort(options);
9758     }
9759
9760     /**
9761      * Moves an activity, and all of the other activities within the same task, to the bottom
9762      * of the history stack.  The activity's order within the task is unchanged.
9763      *
9764      * @param token A reference to the activity we wish to move
9765      * @param nonRoot If false then this only works if the activity is the root
9766      *                of a task; if true it will work for any activity in a task.
9767      * @return Returns true if the move completed, false if not.
9768      */
9769     @Override
9770     public boolean moveActivityTaskToBack(IBinder token, boolean nonRoot) {
9771         enforceNotIsolatedCaller("moveActivityTaskToBack");
9772         synchronized(this) {
9773             final long origId = Binder.clearCallingIdentity();
9774             try {
9775                 int taskId = ActivityRecord.getTaskForActivityLocked(token, !nonRoot);
9776                 final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
9777                 if (task != null) {
9778                     if (mStackSupervisor.isLockedTask(task)) {
9779                         mStackSupervisor.showLockTaskToast();
9780                         return false;
9781                     }
9782                     return ActivityRecord.getStackLocked(token).moveTaskToBackLocked(taskId);
9783                 }
9784             } finally {
9785                 Binder.restoreCallingIdentity(origId);
9786             }
9787         }
9788         return false;
9789     }
9790
9791     @Override
9792     public void moveTaskBackwards(int task) {
9793         enforceCallingPermission(android.Manifest.permission.REORDER_TASKS,
9794                 "moveTaskBackwards()");
9795
9796         synchronized(this) {
9797             if (!checkAppSwitchAllowedLocked(Binder.getCallingPid(),
9798                     Binder.getCallingUid(), -1, -1, "Task backwards")) {
9799                 return;
9800             }
9801             final long origId = Binder.clearCallingIdentity();
9802             moveTaskBackwardsLocked(task);
9803             Binder.restoreCallingIdentity(origId);
9804         }
9805     }
9806
9807     private final void moveTaskBackwardsLocked(int task) {
9808         Slog.e(TAG, "moveTaskBackwards not yet implemented!");
9809     }
9810
9811     @Override
9812     public IActivityContainer createVirtualActivityContainer(IBinder parentActivityToken,
9813             IActivityContainerCallback callback) throws RemoteException {
9814         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createActivityContainer()");
9815         synchronized (this) {
9816             if (parentActivityToken == null) {
9817                 throw new IllegalArgumentException("parent token must not be null");
9818             }
9819             ActivityRecord r = ActivityRecord.forTokenLocked(parentActivityToken);
9820             if (r == null) {
9821                 return null;
9822             }
9823             if (callback == null) {
9824                 throw new IllegalArgumentException("callback must not be null");
9825             }
9826             return mStackSupervisor.createVirtualActivityContainer(r, callback);
9827         }
9828     }
9829
9830     @Override
9831     public void deleteActivityContainer(IActivityContainer container) throws RemoteException {
9832         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "deleteActivityContainer()");
9833         synchronized (this) {
9834             mStackSupervisor.deleteActivityContainer(container);
9835         }
9836     }
9837
9838     @Override
9839     public IActivityContainer createStackOnDisplay(int displayId) throws RemoteException {
9840         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "createStackOnDisplay()");
9841         synchronized (this) {
9842             final int stackId = mStackSupervisor.getNextStackId();
9843             final ActivityStack stack =
9844                     mStackSupervisor.createStackOnDisplay(stackId, displayId, true /*onTop*/);
9845             if (stack == null) {
9846                 return null;
9847             }
9848             return stack.mActivityContainer;
9849         }
9850     }
9851
9852     @Override
9853     public int getActivityDisplayId(IBinder activityToken) throws RemoteException {
9854         synchronized (this) {
9855             ActivityStack stack = ActivityRecord.getStackLocked(activityToken);
9856             if (stack != null && stack.mActivityContainer.isAttachedLocked()) {
9857                 return stack.mActivityContainer.getDisplayId();
9858             }
9859             return Display.DEFAULT_DISPLAY;
9860         }
9861     }
9862
9863     @Override
9864     public int getActivityStackId(IBinder token) throws RemoteException {
9865         synchronized (this) {
9866             ActivityStack stack = ActivityRecord.getStackLocked(token);
9867             if (stack == null) {
9868                 return INVALID_STACK_ID;
9869             }
9870             return stack.mStackId;
9871         }
9872     }
9873
9874     @Override
9875     public void exitFreeformMode(IBinder token) throws RemoteException {
9876         synchronized (this) {
9877             long ident = Binder.clearCallingIdentity();
9878             try {
9879                 final ActivityRecord r = ActivityRecord.forTokenLocked(token);
9880                 if (r == null) {
9881                     throw new IllegalArgumentException(
9882                             "exitFreeformMode: No activity record matching token=" + token);
9883                 }
9884                 final ActivityStack stack = r.getStackLocked(token);
9885                 if (stack == null || stack.mStackId != FREEFORM_WORKSPACE_STACK_ID) {
9886                     throw new IllegalStateException(
9887                             "exitFreeformMode: You can only go fullscreen from freeform.");
9888                 }
9889                 if (DEBUG_STACK) Slog.d(TAG_STACK, "exitFreeformMode: " + r);
9890                 mStackSupervisor.moveTaskToStackLocked(r.task.taskId, FULLSCREEN_WORKSPACE_STACK_ID,
9891                         ON_TOP, !FORCE_FOCUS, "exitFreeformMode", ANIMATE);
9892             } finally {
9893                 Binder.restoreCallingIdentity(ident);
9894             }
9895         }
9896     }
9897
9898     @Override
9899     public void moveTaskToStack(int taskId, int stackId, boolean toTop) {
9900         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToStack()");
9901         if (stackId == HOME_STACK_ID) {
9902             throw new IllegalArgumentException(
9903                     "moveTaskToStack: Attempt to move task " + taskId + " to home stack");
9904         }
9905         synchronized (this) {
9906             long ident = Binder.clearCallingIdentity();
9907             try {
9908                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToStack: moving task=" + taskId
9909                         + " to stackId=" + stackId + " toTop=" + toTop);
9910                 if (stackId == DOCKED_STACK_ID) {
9911                     mWindowManager.setDockedStackCreateState(DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT,
9912                             null /* initialBounds */);
9913                 }
9914                 boolean result = mStackSupervisor.moveTaskToStackLocked(taskId, stackId, toTop,
9915                         !FORCE_FOCUS, "moveTaskToStack", ANIMATE);
9916                 if (result && stackId == DOCKED_STACK_ID) {
9917                     // If task moved to docked stack - show recents if needed.
9918                     mStackSupervisor.moveHomeStackTaskToTop(RECENTS_ACTIVITY_TYPE,
9919                             "moveTaskToDockedStack");
9920                 }
9921             } finally {
9922                 Binder.restoreCallingIdentity(ident);
9923             }
9924         }
9925     }
9926
9927     @Override
9928     public void swapDockedAndFullscreenStack() throws RemoteException {
9929         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "swapDockedAndFullscreenStack()");
9930         synchronized (this) {
9931             long ident = Binder.clearCallingIdentity();
9932             try {
9933                 final ActivityStack fullscreenStack = mStackSupervisor.getStack(
9934                         FULLSCREEN_WORKSPACE_STACK_ID);
9935                 final TaskRecord topTask = fullscreenStack != null ? fullscreenStack.topTask()
9936                         : null;
9937                 final ActivityStack dockedStack = mStackSupervisor.getStack(DOCKED_STACK_ID);
9938                 final ArrayList<TaskRecord> tasks = dockedStack != null ? dockedStack.getAllTasks()
9939                         : null;
9940                 if (topTask == null || tasks == null || tasks.size() == 0) {
9941                     Slog.w(TAG,
9942                             "Unable to swap tasks, either docked or fullscreen stack is empty.");
9943                     return;
9944                 }
9945
9946                 // TODO: App transition
9947                 mWindowManager.prepareAppTransition(TRANSIT_ACTIVITY_RELAUNCH, false);
9948
9949                 // Defer the resume so resume/pausing while moving stacks is dangerous.
9950                 mStackSupervisor.moveTaskToStackLocked(topTask.taskId, DOCKED_STACK_ID,
9951                         false /* toTop */, !FORCE_FOCUS, "swapDockedAndFullscreenStack",
9952                         ANIMATE, true /* deferResume */);
9953                 final int size = tasks.size();
9954                 for (int i = 0; i < size; i++) {
9955                     final int id = tasks.get(i).taskId;
9956                     if (id == topTask.taskId) {
9957                         continue;
9958                     }
9959                     mStackSupervisor.moveTaskToStackLocked(id,
9960                             FULLSCREEN_WORKSPACE_STACK_ID, true /* toTop */, !FORCE_FOCUS,
9961                             "swapDockedAndFullscreenStack", ANIMATE, true /* deferResume */);
9962                 }
9963
9964                 // Because we deferred the resume, to avoid conflicts with stack switches while
9965                 // resuming, we need to do it after all the tasks are moved.
9966                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
9967                 mStackSupervisor.resumeFocusedStackTopActivityLocked();
9968
9969                 mWindowManager.executeAppTransition();
9970             } finally {
9971                 Binder.restoreCallingIdentity(ident);
9972             }
9973         }
9974     }
9975
9976     /**
9977      * Moves the input task to the docked stack.
9978      *
9979      * @param taskId Id of task to move.
9980      * @param createMode The mode the docked stack should be created in if it doesn't exist
9981      *                   already. See
9982      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_TOP_OR_LEFT}
9983      *                   and
9984      *                   {@link android.app.ActivityManager#DOCKED_STACK_CREATE_MODE_BOTTOM_OR_RIGHT}
9985      * @param toTop If the task and stack should be moved to the top.
9986      * @param animate Whether we should play an animation for the moving the task
9987      * @param initialBounds If the docked stack gets created, it will use these bounds for the
9988      *                      docked stack. Pass {@code null} to use default bounds.
9989      */
9990     @Override
9991     public boolean moveTaskToDockedStack(int taskId, int createMode, boolean toTop, boolean animate,
9992             Rect initialBounds, boolean moveHomeStackFront) {
9993         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTaskToDockedStack()");
9994         synchronized (this) {
9995             long ident = Binder.clearCallingIdentity();
9996             try {
9997                 if (DEBUG_STACK) Slog.d(TAG_STACK, "moveTaskToDockedStack: moving task=" + taskId
9998                         + " to createMode=" + createMode + " toTop=" + toTop);
9999                 mWindowManager.setDockedStackCreateState(createMode, initialBounds);
10000                 final boolean moved = mStackSupervisor.moveTaskToStackLocked(
10001                         taskId, DOCKED_STACK_ID, toTop, !FORCE_FOCUS, "moveTaskToDockedStack",
10002                         animate, DEFER_RESUME);
10003                 if (moved) {
10004                     if (moveHomeStackFront) {
10005                         mStackSupervisor.moveHomeStackToFront("moveTaskToDockedStack");
10006                     }
10007                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
10008                 }
10009                 return moved;
10010             } finally {
10011                 Binder.restoreCallingIdentity(ident);
10012             }
10013         }
10014     }
10015
10016     /**
10017      * Moves the top activity in the input stackId to the pinned stack.
10018      *
10019      * @param stackId Id of stack to move the top activity to pinned stack.
10020      * @param bounds Bounds to use for pinned stack.
10021      *
10022      * @return True if the top activity of the input stack was successfully moved to the pinned
10023      *          stack.
10024      */
10025     @Override
10026     public boolean moveTopActivityToPinnedStack(int stackId, Rect bounds) {
10027         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTopActivityToPinnedStack()");
10028         synchronized (this) {
10029             if (!mSupportsPictureInPicture) {
10030                 throw new IllegalStateException("moveTopActivityToPinnedStack:"
10031                         + "Device doesn't support picture-in-pciture mode");
10032             }
10033
10034             long ident = Binder.clearCallingIdentity();
10035             try {
10036                 return mStackSupervisor.moveTopStackActivityToPinnedStackLocked(stackId, bounds);
10037             } finally {
10038                 Binder.restoreCallingIdentity(ident);
10039             }
10040         }
10041     }
10042
10043     @Override
10044     public void resizeStack(int stackId, Rect bounds, boolean allowResizeInDockedMode,
10045             boolean preserveWindows, boolean animate, int animationDuration) {
10046         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "resizeStack()");
10047         long ident = Binder.clearCallingIdentity();
10048         try {
10049             synchronized (this) {
10050                 if (animate) {
10051                     if (stackId == PINNED_STACK_ID) {
10052                         mWindowManager.animateResizePinnedStack(bounds, animationDuration);
10053                     } else {
10054                         throw new IllegalArgumentException("Stack: " + stackId
10055                                 + " doesn't support animated resize.");
10056                     }
10057                 } else {
10058                     mStackSupervisor.resizeStackLocked(stackId, bounds, null /* tempTaskBounds */,
10059                             null /* tempTaskInsetBounds */, preserveWindows,
10060                             allowResizeInDockedMode, !DEFER_RESUME);
10061                 }
10062             }
10063         } finally {
10064             Binder.restoreCallingIdentity(ident);
10065         }
10066     }
10067
10068     @Override
10069     public void resizeDockedStack(Rect dockedBounds, Rect tempDockedTaskBounds,
10070             Rect tempDockedTaskInsetBounds,
10071             Rect tempOtherTaskBounds, Rect tempOtherTaskInsetBounds) {
10072         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10073                 "resizeDockedStack()");
10074         long ident = Binder.clearCallingIdentity();
10075         try {
10076             synchronized (this) {
10077                 mStackSupervisor.resizeDockedStackLocked(dockedBounds, tempDockedTaskBounds,
10078                         tempDockedTaskInsetBounds, tempOtherTaskBounds, tempOtherTaskInsetBounds,
10079                         PRESERVE_WINDOWS);
10080             }
10081         } finally {
10082             Binder.restoreCallingIdentity(ident);
10083         }
10084     }
10085
10086     @Override
10087     public void resizePinnedStack(Rect pinnedBounds, Rect tempPinnedTaskBounds) {
10088         enforceCallingPermission(android.Manifest.permission.MANAGE_ACTIVITY_STACKS,
10089                 "resizePinnedStack()");
10090         final long ident = Binder.clearCallingIdentity();
10091         try {
10092             synchronized (this) {
10093                 mStackSupervisor.resizePinnedStackLocked(pinnedBounds, tempPinnedTaskBounds);
10094             }
10095         } finally {
10096             Binder.restoreCallingIdentity(ident);
10097         }
10098     }
10099
10100     @Override
10101     public void positionTaskInStack(int taskId, int stackId, int position) {
10102         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "positionTaskInStack()");
10103         if (stackId == HOME_STACK_ID) {
10104             throw new IllegalArgumentException(
10105                     "positionTaskInStack: Attempt to change the position of task "
10106                     + taskId + " in/to home stack");
10107         }
10108         synchronized (this) {
10109             long ident = Binder.clearCallingIdentity();
10110             try {
10111                 if (DEBUG_STACK) Slog.d(TAG_STACK,
10112                         "positionTaskInStack: positioning task=" + taskId
10113                         + " in stackId=" + stackId + " at position=" + position);
10114                 mStackSupervisor.positionTaskInStackLocked(taskId, stackId, position);
10115             } finally {
10116                 Binder.restoreCallingIdentity(ident);
10117             }
10118         }
10119     }
10120
10121     @Override
10122     public List<StackInfo> getAllStackInfos() {
10123         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getAllStackInfos()");
10124         long ident = Binder.clearCallingIdentity();
10125         try {
10126             synchronized (this) {
10127                 return mStackSupervisor.getAllStackInfosLocked();
10128             }
10129         } finally {
10130             Binder.restoreCallingIdentity(ident);
10131         }
10132     }
10133
10134     @Override
10135     public StackInfo getStackInfo(int stackId) {
10136         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10137         long ident = Binder.clearCallingIdentity();
10138         try {
10139             synchronized (this) {
10140                 return mStackSupervisor.getStackInfoLocked(stackId);
10141             }
10142         } finally {
10143             Binder.restoreCallingIdentity(ident);
10144         }
10145     }
10146
10147     @Override
10148     public boolean isInHomeStack(int taskId) {
10149         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "getStackInfo()");
10150         long ident = Binder.clearCallingIdentity();
10151         try {
10152             synchronized (this) {
10153                 final TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(
10154                         taskId, !RESTORE_FROM_RECENTS, INVALID_STACK_ID);
10155                 return tr != null && tr.stack != null && tr.stack.isHomeStack();
10156             }
10157         } finally {
10158             Binder.restoreCallingIdentity(ident);
10159         }
10160     }
10161
10162     @Override
10163     public int getTaskForActivity(IBinder token, boolean onlyRoot) {
10164         synchronized(this) {
10165             return ActivityRecord.getTaskForActivityLocked(token, onlyRoot);
10166         }
10167     }
10168
10169     @Override
10170     public void updateDeviceOwner(String packageName) {
10171         final int callingUid = Binder.getCallingUid();
10172         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10173             throw new SecurityException("updateDeviceOwner called from non-system process");
10174         }
10175         synchronized (this) {
10176             mDeviceOwnerName = packageName;
10177         }
10178     }
10179
10180     @Override
10181     public void updateLockTaskPackages(int userId, String[] packages) {
10182         final int callingUid = Binder.getCallingUid();
10183         if (callingUid != 0 && callingUid != Process.SYSTEM_UID) {
10184             enforceCallingPermission(android.Manifest.permission.UPDATE_LOCK_TASK_PACKAGES,
10185                     "updateLockTaskPackages()");
10186         }
10187         synchronized (this) {
10188             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Whitelisting " + userId + ":" +
10189                     Arrays.toString(packages));
10190             mLockTaskPackages.put(userId, packages);
10191             mStackSupervisor.onLockTaskPackagesUpdatedLocked();
10192         }
10193     }
10194
10195
10196     void startLockTaskModeLocked(TaskRecord task) {
10197         if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "startLockTaskModeLocked: " + task);
10198         if (task.mLockTaskAuth == LOCK_TASK_AUTH_DONT_LOCK) {
10199             return;
10200         }
10201
10202         // isSystemInitiated is used to distinguish between locked and pinned mode, as pinned mode
10203         // is initiated by system after the pinning request was shown and locked mode is initiated
10204         // by an authorized app directly
10205         final int callingUid = Binder.getCallingUid();
10206         boolean isSystemInitiated = callingUid == Process.SYSTEM_UID;
10207         long ident = Binder.clearCallingIdentity();
10208         try {
10209             if (!isSystemInitiated) {
10210                 task.mLockTaskUid = callingUid;
10211                 if (task.mLockTaskAuth == LOCK_TASK_AUTH_PINNABLE) {
10212                     // startLockTask() called by app and task mode is lockTaskModeDefault.
10213                     if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, "Mode default, asking user");
10214                     StatusBarManagerInternal statusBarManager =
10215                             LocalServices.getService(StatusBarManagerInternal.class);
10216                     if (statusBarManager != null) {
10217                         statusBarManager.showScreenPinningRequest(task.taskId);
10218                     }
10219                     return;
10220                 }
10221
10222                 final ActivityStack stack = mStackSupervisor.getFocusedStack();
10223                 if (stack == null || task != stack.topTask()) {
10224                     throw new IllegalArgumentException("Invalid task, not in foreground");
10225                 }
10226             }
10227             if (DEBUG_LOCKTASK) Slog.w(TAG_LOCKTASK, isSystemInitiated ? "Locking pinned" :
10228                     "Locking fully");
10229             mStackSupervisor.setLockTaskModeLocked(task, isSystemInitiated ?
10230                     ActivityManager.LOCK_TASK_MODE_PINNED :
10231                     ActivityManager.LOCK_TASK_MODE_LOCKED,
10232                     "startLockTask", true);
10233         } finally {
10234             Binder.restoreCallingIdentity(ident);
10235         }
10236     }
10237
10238     @Override
10239     public void startLockTaskMode(int taskId) {
10240         synchronized (this) {
10241             final TaskRecord task = mStackSupervisor.anyTaskForIdLocked(taskId);
10242             if (task != null) {
10243                 startLockTaskModeLocked(task);
10244             }
10245         }
10246     }
10247
10248     @Override
10249     public void startLockTaskMode(IBinder token) {
10250         synchronized (this) {
10251             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10252             if (r == null) {
10253                 return;
10254             }
10255             final TaskRecord task = r.task;
10256             if (task != null) {
10257                 startLockTaskModeLocked(task);
10258             }
10259         }
10260     }
10261
10262     @Override
10263     public void startSystemLockTaskMode(int taskId) throws RemoteException {
10264         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startSystemLockTaskMode");
10265         // This makes inner call to look as if it was initiated by system.
10266         long ident = Binder.clearCallingIdentity();
10267         try {
10268             synchronized (this) {
10269                 startLockTaskMode(taskId);
10270             }
10271         } finally {
10272             Binder.restoreCallingIdentity(ident);
10273         }
10274     }
10275
10276     @Override
10277     public void stopLockTaskMode() {
10278         final TaskRecord lockTask = mStackSupervisor.getLockedTaskLocked();
10279         if (lockTask == null) {
10280             // Our work here is done.
10281             return;
10282         }
10283
10284         final int callingUid = Binder.getCallingUid();
10285         final int lockTaskUid = lockTask.mLockTaskUid;
10286         final int lockTaskModeState = mStackSupervisor.getLockTaskModeState();
10287         if (lockTaskModeState == ActivityManager.LOCK_TASK_MODE_NONE) {
10288             // Done.
10289             return;
10290         } else {
10291             // Ensure the same caller for startLockTaskMode and stopLockTaskMode.
10292             // It is possible lockTaskMode was started by the system process because
10293             // android:lockTaskMode is set to a locking value in the application manifest
10294             // instead of the app calling startLockTaskMode. In this case
10295             // {@link TaskRecord.mLockTaskUid} will be 0, so we compare the callingUid to the
10296             // {@link TaskRecord.effectiveUid} instead. Also caller with
10297             // {@link MANAGE_ACTIVITY_STACKS} can stop any lock task.
10298             if (checkCallingPermission(MANAGE_ACTIVITY_STACKS) != PERMISSION_GRANTED
10299                     && callingUid != lockTaskUid
10300                     && (lockTaskUid != 0 || callingUid != lockTask.effectiveUid)) {
10301                 throw new SecurityException("Invalid uid, expected " + lockTaskUid
10302                         + " callingUid=" + callingUid + " effectiveUid=" + lockTask.effectiveUid);
10303             }
10304         }
10305         long ident = Binder.clearCallingIdentity();
10306         try {
10307             Log.d(TAG, "stopLockTaskMode");
10308             // Stop lock task
10309             synchronized (this) {
10310                 mStackSupervisor.setLockTaskModeLocked(null, ActivityManager.LOCK_TASK_MODE_NONE,
10311                         "stopLockTask", true);
10312             }
10313             TelecomManager tm = (TelecomManager) mContext.getSystemService(Context.TELECOM_SERVICE);
10314             if (tm != null) {
10315                 tm.showInCallScreen(false);
10316             }
10317         } finally {
10318             Binder.restoreCallingIdentity(ident);
10319         }
10320     }
10321
10322     /**
10323      * This API should be called by SystemUI only when user perform certain action to dismiss
10324      * lock task mode. We should only dismiss pinned lock task mode in this case.
10325      */
10326     @Override
10327     public void stopSystemLockTaskMode() throws RemoteException {
10328         if (mStackSupervisor.getLockTaskModeState() == ActivityManager.LOCK_TASK_MODE_PINNED) {
10329             stopLockTaskMode();
10330         } else {
10331             mStackSupervisor.showLockTaskToast();
10332         }
10333     }
10334
10335     @Override
10336     public boolean isInLockTaskMode() {
10337         return getLockTaskModeState() != ActivityManager.LOCK_TASK_MODE_NONE;
10338     }
10339
10340     @Override
10341     public int getLockTaskModeState() {
10342         synchronized (this) {
10343             return mStackSupervisor.getLockTaskModeState();
10344         }
10345     }
10346
10347     @Override
10348     public void showLockTaskEscapeMessage(IBinder token) {
10349         synchronized (this) {
10350             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
10351             if (r == null) {
10352                 return;
10353             }
10354             mStackSupervisor.showLockTaskEscapeMessageLocked(r.task);
10355         }
10356     }
10357
10358     // =========================================================
10359     // CONTENT PROVIDERS
10360     // =========================================================
10361
10362     private final List<ProviderInfo> generateApplicationProvidersLocked(ProcessRecord app) {
10363         List<ProviderInfo> providers = null;
10364         try {
10365             providers = AppGlobals.getPackageManager()
10366                     .queryContentProviders(app.processName, app.uid,
10367                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10368                                     | MATCH_DEBUG_TRIAGED_MISSING)
10369                     .getList();
10370         } catch (RemoteException ex) {
10371         }
10372         if (DEBUG_MU) Slog.v(TAG_MU,
10373                 "generateApplicationProvidersLocked, app.info.uid = " + app.uid);
10374         int userId = app.userId;
10375         if (providers != null) {
10376             int N = providers.size();
10377             app.pubProviders.ensureCapacity(N + app.pubProviders.size());
10378             for (int i=0; i<N; i++) {
10379                 // TODO: keep logic in sync with installEncryptionUnawareProviders
10380                 ProviderInfo cpi =
10381                     (ProviderInfo)providers.get(i);
10382                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10383                         cpi.name, cpi.flags);
10384                 if (singleton && UserHandle.getUserId(app.uid) != UserHandle.USER_SYSTEM) {
10385                     // This is a singleton provider, but a user besides the
10386                     // default user is asking to initialize a process it runs
10387                     // in...  well, no, it doesn't actually run in this process,
10388                     // it runs in the process of the default user.  Get rid of it.
10389                     providers.remove(i);
10390                     N--;
10391                     i--;
10392                     continue;
10393                 }
10394
10395                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10396                 ContentProviderRecord cpr = mProviderMap.getProviderByClass(comp, userId);
10397                 if (cpr == null) {
10398                     cpr = new ContentProviderRecord(this, cpi, app.info, comp, singleton);
10399                     mProviderMap.putProviderByClass(comp, cpr);
10400                 }
10401                 if (DEBUG_MU) Slog.v(TAG_MU,
10402                         "generateApplicationProvidersLocked, cpi.uid = " + cpr.uid);
10403                 app.pubProviders.put(cpi.name, cpr);
10404                 if (!cpi.multiprocess || !"android".equals(cpi.packageName)) {
10405                     // Don't add this if it is a platform component that is marked
10406                     // to run in multiple processes, because this is actually
10407                     // part of the framework so doesn't make sense to track as a
10408                     // separate apk in the process.
10409                     app.addPackage(cpi.applicationInfo.packageName, cpi.applicationInfo.versionCode,
10410                             mProcessStats);
10411                 }
10412                 notifyPackageUse(cpi.applicationInfo.packageName,
10413                                  PackageManager.NOTIFY_PACKAGE_USE_CONTENT_PROVIDER);
10414             }
10415         }
10416         return providers;
10417     }
10418
10419     /**
10420      * Check if the calling UID has a possible chance at accessing the provider
10421      * at the given authority and user.
10422      */
10423     public String checkContentProviderAccess(String authority, int userId) {
10424         if (userId == UserHandle.USER_ALL) {
10425             mContext.enforceCallingOrSelfPermission(
10426                     Manifest.permission.INTERACT_ACROSS_USERS_FULL, TAG);
10427             userId = UserHandle.getCallingUserId();
10428         }
10429
10430         ProviderInfo cpi = null;
10431         try {
10432             cpi = AppGlobals.getPackageManager().resolveContentProvider(authority,
10433                     STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS
10434                             | PackageManager.MATCH_DIRECT_BOOT_AWARE
10435                             | PackageManager.MATCH_DIRECT_BOOT_UNAWARE,
10436                     userId);
10437         } catch (RemoteException ignored) {
10438         }
10439         if (cpi == null) {
10440             // TODO: make this an outright failure in a future platform release;
10441             // until then anonymous content notifications are unprotected
10442             //return "Failed to find provider " + authority + " for user " + userId;
10443             return null;
10444         }
10445
10446         ProcessRecord r = null;
10447         synchronized (mPidsSelfLocked) {
10448             r = mPidsSelfLocked.get(Binder.getCallingPid());
10449         }
10450         if (r == null) {
10451             return "Failed to find PID " + Binder.getCallingPid();
10452         }
10453
10454         synchronized (this) {
10455             return checkContentProviderPermissionLocked(cpi, r, userId, true);
10456         }
10457     }
10458
10459     /**
10460      * Check if {@link ProcessRecord} has a possible chance at accessing the
10461      * given {@link ProviderInfo}. Final permission checking is always done
10462      * in {@link ContentProvider}.
10463      */
10464     private final String checkContentProviderPermissionLocked(
10465             ProviderInfo cpi, ProcessRecord r, int userId, boolean checkUser) {
10466         final int callingPid = (r != null) ? r.pid : Binder.getCallingPid();
10467         final int callingUid = (r != null) ? r.uid : Binder.getCallingUid();
10468         boolean checkedGrants = false;
10469         if (checkUser) {
10470             // Looking for cross-user grants before enforcing the typical cross-users permissions
10471             int tmpTargetUserId = mUserController.unsafeConvertIncomingUserLocked(userId);
10472             if (tmpTargetUserId != UserHandle.getUserId(callingUid)) {
10473                 if (checkAuthorityGrants(callingUid, cpi, tmpTargetUserId, checkUser)) {
10474                     return null;
10475                 }
10476                 checkedGrants = true;
10477             }
10478             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, false,
10479                     ALLOW_NON_FULL, "checkContentProviderPermissionLocked " + cpi.authority, null);
10480             if (userId != tmpTargetUserId) {
10481                 // When we actually went to determine the final targer user ID, this ended
10482                 // up different than our initial check for the authority.  This is because
10483                 // they had asked for USER_CURRENT_OR_SELF and we ended up switching to
10484                 // SELF.  So we need to re-check the grants again.
10485                 checkedGrants = false;
10486             }
10487         }
10488         if (checkComponentPermission(cpi.readPermission, callingPid, callingUid,
10489                 cpi.applicationInfo.uid, cpi.exported)
10490                 == PackageManager.PERMISSION_GRANTED) {
10491             return null;
10492         }
10493         if (checkComponentPermission(cpi.writePermission, callingPid, callingUid,
10494                 cpi.applicationInfo.uid, cpi.exported)
10495                 == PackageManager.PERMISSION_GRANTED) {
10496             return null;
10497         }
10498
10499         PathPermission[] pps = cpi.pathPermissions;
10500         if (pps != null) {
10501             int i = pps.length;
10502             while (i > 0) {
10503                 i--;
10504                 PathPermission pp = pps[i];
10505                 String pprperm = pp.getReadPermission();
10506                 if (pprperm != null && checkComponentPermission(pprperm, callingPid, callingUid,
10507                         cpi.applicationInfo.uid, cpi.exported)
10508                         == PackageManager.PERMISSION_GRANTED) {
10509                     return null;
10510                 }
10511                 String ppwperm = pp.getWritePermission();
10512                 if (ppwperm != null && checkComponentPermission(ppwperm, callingPid, callingUid,
10513                         cpi.applicationInfo.uid, cpi.exported)
10514                         == PackageManager.PERMISSION_GRANTED) {
10515                     return null;
10516                 }
10517             }
10518         }
10519         if (!checkedGrants && checkAuthorityGrants(callingUid, cpi, userId, checkUser)) {
10520             return null;
10521         }
10522
10523         String msg;
10524         if (!cpi.exported) {
10525             msg = "Permission Denial: opening provider " + cpi.name
10526                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10527                     + ", uid=" + callingUid + ") that is not exported from uid "
10528                     + cpi.applicationInfo.uid;
10529         } else {
10530             msg = "Permission Denial: opening provider " + cpi.name
10531                     + " from " + (r != null ? r : "(null)") + " (pid=" + callingPid
10532                     + ", uid=" + callingUid + ") requires "
10533                     + cpi.readPermission + " or " + cpi.writePermission;
10534         }
10535         Slog.w(TAG, msg);
10536         return msg;
10537     }
10538
10539     /**
10540      * Returns if the ContentProvider has granted a uri to callingUid
10541      */
10542     boolean checkAuthorityGrants(int callingUid, ProviderInfo cpi, int userId, boolean checkUser) {
10543         final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.get(callingUid);
10544         if (perms != null) {
10545             for (int i=perms.size()-1; i>=0; i--) {
10546                 GrantUri grantUri = perms.keyAt(i);
10547                 if (grantUri.sourceUserId == userId || !checkUser) {
10548                     if (matchesProvider(grantUri.uri, cpi)) {
10549                         return true;
10550                     }
10551                 }
10552             }
10553         }
10554         return false;
10555     }
10556
10557     /**
10558      * Returns true if the uri authority is one of the authorities specified in the provider.
10559      */
10560     boolean matchesProvider(Uri uri, ProviderInfo cpi) {
10561         String uriAuth = uri.getAuthority();
10562         String cpiAuth = cpi.authority;
10563         if (cpiAuth.indexOf(';') == -1) {
10564             return cpiAuth.equals(uriAuth);
10565         }
10566         String[] cpiAuths = cpiAuth.split(";");
10567         int length = cpiAuths.length;
10568         for (int i = 0; i < length; i++) {
10569             if (cpiAuths[i].equals(uriAuth)) return true;
10570         }
10571         return false;
10572     }
10573
10574     ContentProviderConnection incProviderCountLocked(ProcessRecord r,
10575             final ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10576         if (r != null) {
10577             for (int i=0; i<r.conProviders.size(); i++) {
10578                 ContentProviderConnection conn = r.conProviders.get(i);
10579                 if (conn.provider == cpr) {
10580                     if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10581                             "Adding provider requested by "
10582                             + r.processName + " from process "
10583                             + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10584                             + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10585                     if (stable) {
10586                         conn.stableCount++;
10587                         conn.numStableIncs++;
10588                     } else {
10589                         conn.unstableCount++;
10590                         conn.numUnstableIncs++;
10591                     }
10592                     return conn;
10593                 }
10594             }
10595             ContentProviderConnection conn = new ContentProviderConnection(cpr, r);
10596             if (stable) {
10597                 conn.stableCount = 1;
10598                 conn.numStableIncs = 1;
10599             } else {
10600                 conn.unstableCount = 1;
10601                 conn.numUnstableIncs = 1;
10602             }
10603             cpr.connections.add(conn);
10604             r.conProviders.add(conn);
10605             startAssociationLocked(r.uid, r.processName, r.curProcState,
10606                     cpr.uid, cpr.name, cpr.info.processName);
10607             return conn;
10608         }
10609         cpr.addExternalProcessHandleLocked(externalProcessToken);
10610         return null;
10611     }
10612
10613     boolean decProviderCountLocked(ContentProviderConnection conn,
10614             ContentProviderRecord cpr, IBinder externalProcessToken, boolean stable) {
10615         if (conn != null) {
10616             cpr = conn.provider;
10617             if (DEBUG_PROVIDER) Slog.v(TAG_PROVIDER,
10618                     "Removing provider requested by "
10619                     + conn.client.processName + " from process "
10620                     + cpr.info.processName + ": " + cpr.name.flattenToShortString()
10621                     + " scnt=" + conn.stableCount + " uscnt=" + conn.unstableCount);
10622             if (stable) {
10623                 conn.stableCount--;
10624             } else {
10625                 conn.unstableCount--;
10626             }
10627             if (conn.stableCount == 0 && conn.unstableCount == 0) {
10628                 cpr.connections.remove(conn);
10629                 conn.client.conProviders.remove(conn);
10630                 if (conn.client.setProcState < ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
10631                     // The client is more important than last activity -- note the time this
10632                     // is happening, so we keep the old provider process around a bit as last
10633                     // activity to avoid thrashing it.
10634                     if (cpr.proc != null) {
10635                         cpr.proc.lastProviderTime = SystemClock.uptimeMillis();
10636                     }
10637                 }
10638                 stopAssociationLocked(conn.client.uid, conn.client.processName, cpr.uid, cpr.name);
10639                 return true;
10640             }
10641             return false;
10642         }
10643         cpr.removeExternalProcessHandleLocked(externalProcessToken);
10644         return false;
10645     }
10646
10647     private void checkTime(long startTime, String where) {
10648         long now = SystemClock.uptimeMillis();
10649         if ((now-startTime) > 50) {
10650             // If we are taking more than 50ms, log about it.
10651             Slog.w(TAG, "Slow operation: " + (now-startTime) + "ms so far, now at " + where);
10652         }
10653     }
10654
10655     private static final int[] PROCESS_STATE_STATS_FORMAT = new int[] {
10656             PROC_SPACE_TERM,
10657             PROC_SPACE_TERM|PROC_PARENS,
10658             PROC_SPACE_TERM|PROC_CHAR|PROC_OUT_LONG,        // 3: process state
10659     };
10660
10661     private final long[] mProcessStateStatsLongs = new long[1];
10662
10663     boolean isProcessAliveLocked(ProcessRecord proc) {
10664         if (proc.procStatFile == null) {
10665             proc.procStatFile = "/proc/" + proc.pid + "/stat";
10666         }
10667         mProcessStateStatsLongs[0] = 0;
10668         if (!Process.readProcFile(proc.procStatFile, PROCESS_STATE_STATS_FORMAT, null,
10669                 mProcessStateStatsLongs, null)) {
10670             if (DEBUG_OOM_ADJ) Slog.d(TAG, "UNABLE TO RETRIEVE STATE FOR " + proc.procStatFile);
10671             return false;
10672         }
10673         final long state = mProcessStateStatsLongs[0];
10674         if (DEBUG_OOM_ADJ) Slog.d(TAG, "RETRIEVED STATE FOR " + proc.procStatFile + ": "
10675                 + (char)state);
10676         return state != 'Z' && state != 'X' && state != 'x' && state != 'K';
10677     }
10678
10679     private ContentProviderHolder getContentProviderImpl(IApplicationThread caller,
10680             String name, IBinder token, boolean stable, int userId) {
10681         ContentProviderRecord cpr;
10682         ContentProviderConnection conn = null;
10683         ProviderInfo cpi = null;
10684
10685         synchronized(this) {
10686             long startTime = SystemClock.uptimeMillis();
10687
10688             ProcessRecord r = null;
10689             if (caller != null) {
10690                 r = getRecordForAppLocked(caller);
10691                 if (r == null) {
10692                     throw new SecurityException(
10693                             "Unable to find app for caller " + caller
10694                           + " (pid=" + Binder.getCallingPid()
10695                           + ") when getting content provider " + name);
10696                 }
10697             }
10698
10699             boolean checkCrossUser = true;
10700
10701             checkTime(startTime, "getContentProviderImpl: getProviderByName");
10702
10703             // First check if this content provider has been published...
10704             cpr = mProviderMap.getProviderByName(name, userId);
10705             // If that didn't work, check if it exists for user 0 and then
10706             // verify that it's a singleton provider before using it.
10707             if (cpr == null && userId != UserHandle.USER_SYSTEM) {
10708                 cpr = mProviderMap.getProviderByName(name, UserHandle.USER_SYSTEM);
10709                 if (cpr != null) {
10710                     cpi = cpr.info;
10711                     if (isSingleton(cpi.processName, cpi.applicationInfo,
10712                             cpi.name, cpi.flags)
10713                             && isValidSingletonCall(r.uid, cpi.applicationInfo.uid)) {
10714                         userId = UserHandle.USER_SYSTEM;
10715                         checkCrossUser = false;
10716                     } else {
10717                         cpr = null;
10718                         cpi = null;
10719                     }
10720                 }
10721             }
10722
10723             boolean providerRunning = cpr != null && cpr.proc != null && !cpr.proc.killed;
10724             if (providerRunning) {
10725                 cpi = cpr.info;
10726                 String msg;
10727                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10728                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, checkCrossUser))
10729                         != null) {
10730                     throw new SecurityException(msg);
10731                 }
10732                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10733
10734                 if (r != null && cpr.canRunHere(r)) {
10735                     // This provider has been published or is in the process
10736                     // of being published...  but it is also allowed to run
10737                     // in the caller's process, so don't make a connection
10738                     // and just let the caller instantiate its own instance.
10739                     ContentProviderHolder holder = cpr.newHolder(null);
10740                     // don't give caller the provider object, it needs
10741                     // to make its own.
10742                     holder.provider = null;
10743                     return holder;
10744                 }
10745
10746                 final long origId = Binder.clearCallingIdentity();
10747
10748                 checkTime(startTime, "getContentProviderImpl: incProviderCountLocked");
10749
10750                 // In this case the provider instance already exists, so we can
10751                 // return it right away.
10752                 conn = incProviderCountLocked(r, cpr, token, stable);
10753                 if (conn != null && (conn.stableCount+conn.unstableCount) == 1) {
10754                     if (cpr.proc != null && r.setAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
10755                         // If this is a perceptible app accessing the provider,
10756                         // make sure to count it as being accessed and thus
10757                         // back up on the LRU list.  This is good because
10758                         // content providers are often expensive to start.
10759                         checkTime(startTime, "getContentProviderImpl: before updateLruProcess");
10760                         updateLruProcessLocked(cpr.proc, false, null);
10761                         checkTime(startTime, "getContentProviderImpl: after updateLruProcess");
10762                     }
10763                 }
10764
10765                 checkTime(startTime, "getContentProviderImpl: before updateOomAdj");
10766                 final int verifiedAdj = cpr.proc.verifiedAdj;
10767                 boolean success = updateOomAdjLocked(cpr.proc);
10768                 // XXX things have changed so updateOomAdjLocked doesn't actually tell us
10769                 // if the process has been successfully adjusted.  So to reduce races with
10770                 // it, we will check whether the process still exists.  Note that this doesn't
10771                 // completely get rid of races with LMK killing the process, but should make
10772                 // them much smaller.
10773                 if (success && verifiedAdj != cpr.proc.setAdj && !isProcessAliveLocked(cpr.proc)) {
10774                     success = false;
10775                 }
10776                 maybeUpdateProviderUsageStatsLocked(r, cpr.info.packageName, name);
10777                 checkTime(startTime, "getContentProviderImpl: after updateOomAdj");
10778                 if (DEBUG_PROVIDER) Slog.i(TAG_PROVIDER, "Adjust success: " + success);
10779                 // NOTE: there is still a race here where a signal could be
10780                 // pending on the process even though we managed to update its
10781                 // adj level.  Not sure what to do about this, but at least
10782                 // the race is now smaller.
10783                 if (!success) {
10784                     // Uh oh...  it looks like the provider's process
10785                     // has been killed on us.  We need to wait for a new
10786                     // process to be started, and make sure its death
10787                     // doesn't kill our process.
10788                     Slog.i(TAG, "Existing provider " + cpr.name.flattenToShortString()
10789                             + " is crashing; detaching " + r);
10790                     boolean lastRef = decProviderCountLocked(conn, cpr, token, stable);
10791                     checkTime(startTime, "getContentProviderImpl: before appDied");
10792                     appDiedLocked(cpr.proc);
10793                     checkTime(startTime, "getContentProviderImpl: after appDied");
10794                     if (!lastRef) {
10795                         // This wasn't the last ref our process had on
10796                         // the provider...  we have now been killed, bail.
10797                         return null;
10798                     }
10799                     providerRunning = false;
10800                     conn = null;
10801                 } else {
10802                     cpr.proc.verifiedAdj = cpr.proc.setAdj;
10803                 }
10804
10805                 Binder.restoreCallingIdentity(origId);
10806             }
10807
10808             if (!providerRunning) {
10809                 try {
10810                     checkTime(startTime, "getContentProviderImpl: before resolveContentProvider");
10811                     cpi = AppGlobals.getPackageManager().
10812                         resolveContentProvider(name,
10813                             STOCK_PM_FLAGS | PackageManager.GET_URI_PERMISSION_PATTERNS, userId);
10814                     checkTime(startTime, "getContentProviderImpl: after resolveContentProvider");
10815                 } catch (RemoteException ex) {
10816                 }
10817                 if (cpi == null) {
10818                     return null;
10819                 }
10820                 // If the provider is a singleton AND
10821                 // (it's a call within the same user || the provider is a
10822                 // privileged app)
10823                 // Then allow connecting to the singleton provider
10824                 boolean singleton = isSingleton(cpi.processName, cpi.applicationInfo,
10825                         cpi.name, cpi.flags)
10826                         && isValidSingletonCall(r.uid, cpi.applicationInfo.uid);
10827                 if (singleton) {
10828                     userId = UserHandle.USER_SYSTEM;
10829                 }
10830                 cpi.applicationInfo = getAppInfoForUser(cpi.applicationInfo, userId);
10831                 checkTime(startTime, "getContentProviderImpl: got app info for user");
10832
10833                 String msg;
10834                 checkTime(startTime, "getContentProviderImpl: before checkContentProviderPermission");
10835                 if ((msg = checkContentProviderPermissionLocked(cpi, r, userId, !singleton))
10836                         != null) {
10837                     throw new SecurityException(msg);
10838                 }
10839                 checkTime(startTime, "getContentProviderImpl: after checkContentProviderPermission");
10840
10841                 if (!mProcessesReady
10842                         && !cpi.processName.equals("system")) {
10843                     // If this content provider does not run in the system
10844                     // process, and the system is not yet ready to run other
10845                     // processes, then fail fast instead of hanging.
10846                     throw new IllegalArgumentException(
10847                             "Attempt to launch content provider before system ready");
10848                 }
10849
10850                 // Make sure that the user who owns this provider is running.  If not,
10851                 // we don't want to allow it to run.
10852                 if (!mUserController.isUserRunningLocked(userId, 0)) {
10853                     Slog.w(TAG, "Unable to launch app "
10854                             + cpi.applicationInfo.packageName + "/"
10855                             + cpi.applicationInfo.uid + " for provider "
10856                             + name + ": user " + userId + " is stopped");
10857                     return null;
10858                 }
10859
10860                 ComponentName comp = new ComponentName(cpi.packageName, cpi.name);
10861                 checkTime(startTime, "getContentProviderImpl: before getProviderByClass");
10862                 cpr = mProviderMap.getProviderByClass(comp, userId);
10863                 checkTime(startTime, "getContentProviderImpl: after getProviderByClass");
10864                 final boolean firstClass = cpr == null;
10865                 if (firstClass) {
10866                     final long ident = Binder.clearCallingIdentity();
10867
10868                     // If permissions need a review before any of the app components can run,
10869                     // we return no provider and launch a review activity if the calling app
10870                     // is in the foreground.
10871                     if (mPermissionReviewRequired || Build.PERMISSIONS_REVIEW_REQUIRED) {
10872                         if (!requestTargetProviderPermissionsReviewIfNeededLocked(cpi, r, userId)) {
10873                             return null;
10874                         }
10875                     }
10876
10877                     try {
10878                         checkTime(startTime, "getContentProviderImpl: before getApplicationInfo");
10879                         ApplicationInfo ai =
10880                             AppGlobals.getPackageManager().
10881                                 getApplicationInfo(
10882                                         cpi.applicationInfo.packageName,
10883                                         STOCK_PM_FLAGS, userId);
10884                         checkTime(startTime, "getContentProviderImpl: after getApplicationInfo");
10885                         if (ai == null) {
10886                             Slog.w(TAG, "No package info for content provider "
10887                                     + cpi.name);
10888                             return null;
10889                         }
10890                         ai = getAppInfoForUser(ai, userId);
10891                         cpr = new ContentProviderRecord(this, cpi, ai, comp, singleton);
10892                     } catch (RemoteException ex) {
10893                         // pm is in same process, this will never happen.
10894                     } finally {
10895                         Binder.restoreCallingIdentity(ident);
10896                     }
10897                 }
10898
10899                 checkTime(startTime, "getContentProviderImpl: now have ContentProviderRecord");
10900
10901                 if (r != null && cpr.canRunHere(r)) {
10902                     // If this is a multiprocess provider, then just return its
10903                     // info and allow the caller to instantiate it.  Only do
10904                     // this if the provider is the same user as the caller's
10905                     // process, or can run as root (so can be in any process).
10906                     return cpr.newHolder(null);
10907                 }
10908
10909                 if (DEBUG_PROVIDER) Slog.w(TAG_PROVIDER, "LAUNCHING REMOTE PROVIDER (myuid "
10910                             + (r != null ? r.uid : null) + " pruid " + cpr.appInfo.uid + "): "
10911                             + cpr.info.name + " callers=" + Debug.getCallers(6));
10912
10913                 // This is single process, and our app is now connecting to it.
10914                 // See if we are already in the process of launching this
10915                 // provider.
10916                 final int N = mLaunchingProviders.size();
10917                 int i;
10918                 for (i = 0; i < N; i++) {
10919                     if (mLaunchingProviders.get(i) == cpr) {
10920                         break;
10921                     }
10922                 }
10923
10924                 // If the provider is not already being launched, then get it
10925                 // started.
10926                 if (i >= N) {
10927                     final long origId = Binder.clearCallingIdentity();
10928
10929                     try {
10930                         // Content provider is now in use, its package can't be stopped.
10931                         try {
10932                             checkTime(startTime, "getContentProviderImpl: before set stopped state");
10933                             AppGlobals.getPackageManager().setPackageStoppedState(
10934                                     cpr.appInfo.packageName, false, userId);
10935                             checkTime(startTime, "getContentProviderImpl: after set stopped state");
10936                         } catch (RemoteException e) {
10937                         } catch (IllegalArgumentException e) {
10938                             Slog.w(TAG, "Failed trying to unstop package "
10939                                     + cpr.appInfo.packageName + ": " + e);
10940                         }
10941
10942                         // Use existing process if already started
10943                         checkTime(startTime, "getContentProviderImpl: looking for process record");
10944                         ProcessRecord proc = getProcessRecordLocked(
10945                                 cpi.processName, cpr.appInfo.uid, false);
10946                         if (proc != null && proc.thread != null && !proc.killed) {
10947                             if (DEBUG_PROVIDER) Slog.d(TAG_PROVIDER,
10948                                     "Installing in existing process " + proc);
10949                             if (!proc.pubProviders.containsKey(cpi.name)) {
10950                                 checkTime(startTime, "getContentProviderImpl: scheduling install");
10951                                 proc.pubProviders.put(cpi.name, cpr);
10952                                 try {
10953                                     proc.thread.scheduleInstallProvider(cpi);
10954                                 } catch (RemoteException e) {
10955                                 }
10956                             }
10957                         } else {
10958                             checkTime(startTime, "getContentProviderImpl: before start process");
10959                             proc = startProcessLocked(cpi.processName,
10960                                     cpr.appInfo, false, 0, "content provider",
10961                                     new ComponentName(cpi.applicationInfo.packageName,
10962                                             cpi.name), false, false, false);
10963                             checkTime(startTime, "getContentProviderImpl: after start process");
10964                             if (proc == null) {
10965                                 Slog.w(TAG, "Unable to launch app "
10966                                         + cpi.applicationInfo.packageName + "/"
10967                                         + cpi.applicationInfo.uid + " for provider "
10968                                         + name + ": process is bad");
10969                                 return null;
10970                             }
10971                         }
10972                         cpr.launchingApp = proc;
10973                         mLaunchingProviders.add(cpr);
10974                     } finally {
10975                         Binder.restoreCallingIdentity(origId);
10976                     }
10977                 }
10978
10979                 checkTime(startTime, "getContentProviderImpl: updating data structures");
10980
10981                 // Make sure the provider is published (the same provider class
10982                 // may be published under multiple names).
10983                 if (firstClass) {
10984                     mProviderMap.putProviderByClass(comp, cpr);
10985                 }
10986
10987                 mProviderMap.putProviderByName(name, cpr);
10988                 conn = incProviderCountLocked(r, cpr, token, stable);
10989                 if (conn != null) {
10990                     conn.waiting = true;
10991                 }
10992             }
10993             checkTime(startTime, "getContentProviderImpl: done!");
10994         }
10995
10996         // Wait for the provider to be published...
10997         synchronized (cpr) {
10998             while (cpr.provider == null) {
10999                 if (cpr.launchingApp == null) {
11000                     Slog.w(TAG, "Unable to launch app "
11001                             + cpi.applicationInfo.packageName + "/"
11002                             + cpi.applicationInfo.uid + " for provider "
11003                             + name + ": launching app became null");
11004                     EventLog.writeEvent(EventLogTags.AM_PROVIDER_LOST_PROCESS,
11005                             UserHandle.getUserId(cpi.applicationInfo.uid),
11006                             cpi.applicationInfo.packageName,
11007                             cpi.applicationInfo.uid, name);
11008                     return null;
11009                 }
11010                 try {
11011                     if (DEBUG_MU) Slog.v(TAG_MU,
11012                             "Waiting to start provider " + cpr
11013                             + " launchingApp=" + cpr.launchingApp);
11014                     if (conn != null) {
11015                         conn.waiting = true;
11016                     }
11017                     cpr.wait();
11018                 } catch (InterruptedException ex) {
11019                 } finally {
11020                     if (conn != null) {
11021                         conn.waiting = false;
11022                     }
11023                 }
11024             }
11025         }
11026         return cpr != null ? cpr.newHolder(conn) : null;
11027     }
11028
11029     private boolean requestTargetProviderPermissionsReviewIfNeededLocked(ProviderInfo cpi,
11030             ProcessRecord r, final int userId) {
11031         if (getPackageManagerInternalLocked().isPermissionsReviewRequired(
11032                 cpi.packageName, userId)) {
11033
11034             final boolean callerForeground = r == null || r.setSchedGroup
11035                     != ProcessList.SCHED_GROUP_BACKGROUND;
11036
11037             // Show a permission review UI only for starting from a foreground app
11038             if (!callerForeground) {
11039                 Slog.w(TAG, "u" + userId + " Instantiating a provider in package"
11040                         + cpi.packageName + " requires a permissions review");
11041                 return false;
11042             }
11043
11044             final Intent intent = new Intent(Intent.ACTION_REVIEW_PERMISSIONS);
11045             intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK
11046                     | Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
11047             intent.putExtra(Intent.EXTRA_PACKAGE_NAME, cpi.packageName);
11048
11049             if (DEBUG_PERMISSIONS_REVIEW) {
11050                 Slog.i(TAG, "u" + userId + " Launching permission review "
11051                         + "for package " + cpi.packageName);
11052             }
11053
11054             final UserHandle userHandle = new UserHandle(userId);
11055             mHandler.post(new Runnable() {
11056                 @Override
11057                 public void run() {
11058                     mContext.startActivityAsUser(intent, userHandle);
11059                 }
11060             });
11061
11062             return false;
11063         }
11064
11065         return true;
11066     }
11067
11068     PackageManagerInternal getPackageManagerInternalLocked() {
11069         if (mPackageManagerInt == null) {
11070             mPackageManagerInt = LocalServices.getService(PackageManagerInternal.class);
11071         }
11072         return mPackageManagerInt;
11073     }
11074
11075     @Override
11076     public final ContentProviderHolder getContentProvider(
11077             IApplicationThread caller, String name, int userId, boolean stable) {
11078         enforceNotIsolatedCaller("getContentProvider");
11079         if (caller == null) {
11080             String msg = "null IApplicationThread when getting content provider "
11081                     + name;
11082             Slog.w(TAG, msg);
11083             throw new SecurityException(msg);
11084         }
11085         // The incoming user check is now handled in checkContentProviderPermissionLocked() to deal
11086         // with cross-user grant.
11087         return getContentProviderImpl(caller, name, null, stable, userId);
11088     }
11089
11090     public ContentProviderHolder getContentProviderExternal(
11091             String name, int userId, IBinder token) {
11092         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11093             "Do not have permission in call getContentProviderExternal()");
11094         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
11095                 userId, false, ALLOW_FULL_ONLY, "getContentProvider", null);
11096         return getContentProviderExternalUnchecked(name, token, userId);
11097     }
11098
11099     private ContentProviderHolder getContentProviderExternalUnchecked(String name,
11100             IBinder token, int userId) {
11101         return getContentProviderImpl(null, name, token, true, userId);
11102     }
11103
11104     /**
11105      * Drop a content provider from a ProcessRecord's bookkeeping
11106      */
11107     public void removeContentProvider(IBinder connection, boolean stable) {
11108         enforceNotIsolatedCaller("removeContentProvider");
11109         long ident = Binder.clearCallingIdentity();
11110         try {
11111             synchronized (this) {
11112                 ContentProviderConnection conn;
11113                 try {
11114                     conn = (ContentProviderConnection)connection;
11115                 } catch (ClassCastException e) {
11116                     String msg ="removeContentProvider: " + connection
11117                             + " not a ContentProviderConnection";
11118                     Slog.w(TAG, msg);
11119                     throw new IllegalArgumentException(msg);
11120                 }
11121                 if (conn == null) {
11122                     throw new NullPointerException("connection is null");
11123                 }
11124                 if (decProviderCountLocked(conn, null, null, stable)) {
11125                     updateOomAdjLocked();
11126                 }
11127             }
11128         } finally {
11129             Binder.restoreCallingIdentity(ident);
11130         }
11131     }
11132
11133     public void removeContentProviderExternal(String name, IBinder token) {
11134         enforceCallingPermission(android.Manifest.permission.ACCESS_CONTENT_PROVIDERS_EXTERNALLY,
11135             "Do not have permission in call removeContentProviderExternal()");
11136         int userId = UserHandle.getCallingUserId();
11137         long ident = Binder.clearCallingIdentity();
11138         try {
11139             removeContentProviderExternalUnchecked(name, token, userId);
11140         } finally {
11141             Binder.restoreCallingIdentity(ident);
11142         }
11143     }
11144
11145     private void removeContentProviderExternalUnchecked(String name, IBinder token, int userId) {
11146         synchronized (this) {
11147             ContentProviderRecord cpr = mProviderMap.getProviderByName(name, userId);
11148             if(cpr == null) {
11149                 //remove from mProvidersByClass
11150                 if(DEBUG_ALL) Slog.v(TAG, name+" content provider not found in providers list");
11151                 return;
11152             }
11153
11154             //update content provider record entry info
11155             ComponentName comp = new ComponentName(cpr.info.packageName, cpr.info.name);
11156             ContentProviderRecord localCpr = mProviderMap.getProviderByClass(comp, userId);
11157             if (localCpr.hasExternalProcessHandles()) {
11158                 if (localCpr.removeExternalProcessHandleLocked(token)) {
11159                     updateOomAdjLocked();
11160                 } else {
11161                     Slog.e(TAG, "Attmpt to remove content provider " + localCpr
11162                             + " with no external reference for token: "
11163                             + token + ".");
11164                 }
11165             } else {
11166                 Slog.e(TAG, "Attmpt to remove content provider: " + localCpr
11167                         + " with no external references.");
11168             }
11169         }
11170     }
11171
11172     public final void publishContentProviders(IApplicationThread caller,
11173             List<ContentProviderHolder> providers) {
11174         if (providers == null) {
11175             return;
11176         }
11177
11178         enforceNotIsolatedCaller("publishContentProviders");
11179         synchronized (this) {
11180             final ProcessRecord r = getRecordForAppLocked(caller);
11181             if (DEBUG_MU) Slog.v(TAG_MU, "ProcessRecord uid = " + r.uid);
11182             if (r == null) {
11183                 throw new SecurityException(
11184                         "Unable to find app for caller " + caller
11185                       + " (pid=" + Binder.getCallingPid()
11186                       + ") when publishing content providers");
11187             }
11188
11189             final long origId = Binder.clearCallingIdentity();
11190
11191             final int N = providers.size();
11192             for (int i = 0; i < N; i++) {
11193                 ContentProviderHolder src = providers.get(i);
11194                 if (src == null || src.info == null || src.provider == null) {
11195                     continue;
11196                 }
11197                 ContentProviderRecord dst = r.pubProviders.get(src.info.name);
11198                 if (DEBUG_MU) Slog.v(TAG_MU, "ContentProviderRecord uid = " + dst.uid);
11199                 if (dst != null) {
11200                     ComponentName comp = new ComponentName(dst.info.packageName, dst.info.name);
11201                     mProviderMap.putProviderByClass(comp, dst);
11202                     String names[] = dst.info.authority.split(";");
11203                     for (int j = 0; j < names.length; j++) {
11204                         mProviderMap.putProviderByName(names[j], dst);
11205                     }
11206
11207                     int launchingCount = mLaunchingProviders.size();
11208                     int j;
11209                     boolean wasInLaunchingProviders = false;
11210                     for (j = 0; j < launchingCount; j++) {
11211                         if (mLaunchingProviders.get(j) == dst) {
11212                             mLaunchingProviders.remove(j);
11213                             wasInLaunchingProviders = true;
11214                             j--;
11215                             launchingCount--;
11216                         }
11217                     }
11218                     if (wasInLaunchingProviders) {
11219                         mHandler.removeMessages(CONTENT_PROVIDER_PUBLISH_TIMEOUT_MSG, r);
11220                     }
11221                     synchronized (dst) {
11222                         dst.provider = src.provider;
11223                         dst.proc = r;
11224                         dst.notifyAll();
11225                     }
11226                     updateOomAdjLocked(r);
11227                     maybeUpdateProviderUsageStatsLocked(r, src.info.packageName,
11228                             src.info.authority);
11229                 }
11230             }
11231
11232             Binder.restoreCallingIdentity(origId);
11233         }
11234     }
11235
11236     public boolean refContentProvider(IBinder connection, int stable, int unstable) {
11237         ContentProviderConnection conn;
11238         try {
11239             conn = (ContentProviderConnection)connection;
11240         } catch (ClassCastException e) {
11241             String msg ="refContentProvider: " + connection
11242                     + " not a ContentProviderConnection";
11243             Slog.w(TAG, msg);
11244             throw new IllegalArgumentException(msg);
11245         }
11246         if (conn == null) {
11247             throw new NullPointerException("connection is null");
11248         }
11249
11250         synchronized (this) {
11251             if (stable > 0) {
11252                 conn.numStableIncs += stable;
11253             }
11254             stable = conn.stableCount + stable;
11255             if (stable < 0) {
11256                 throw new IllegalStateException("stableCount < 0: " + stable);
11257             }
11258
11259             if (unstable > 0) {
11260                 conn.numUnstableIncs += unstable;
11261             }
11262             unstable = conn.unstableCount + unstable;
11263             if (unstable < 0) {
11264                 throw new IllegalStateException("unstableCount < 0: " + unstable);
11265             }
11266
11267             if ((stable+unstable) <= 0) {
11268                 throw new IllegalStateException("ref counts can't go to zero here: stable="
11269                         + stable + " unstable=" + unstable);
11270             }
11271             conn.stableCount = stable;
11272             conn.unstableCount = unstable;
11273             return !conn.dead;
11274         }
11275     }
11276
11277     public void unstableProviderDied(IBinder connection) {
11278         ContentProviderConnection conn;
11279         try {
11280             conn = (ContentProviderConnection)connection;
11281         } catch (ClassCastException e) {
11282             String msg ="refContentProvider: " + connection
11283                     + " not a ContentProviderConnection";
11284             Slog.w(TAG, msg);
11285             throw new IllegalArgumentException(msg);
11286         }
11287         if (conn == null) {
11288             throw new NullPointerException("connection is null");
11289         }
11290
11291         // Safely retrieve the content provider associated with the connection.
11292         IContentProvider provider;
11293         synchronized (this) {
11294             provider = conn.provider.provider;
11295         }
11296
11297         if (provider == null) {
11298             // Um, yeah, we're way ahead of you.
11299             return;
11300         }
11301
11302         // Make sure the caller is being honest with us.
11303         if (provider.asBinder().pingBinder()) {
11304             // Er, no, still looks good to us.
11305             synchronized (this) {
11306                 Slog.w(TAG, "unstableProviderDied: caller " + Binder.getCallingUid()
11307                         + " says " + conn + " died, but we don't agree");
11308                 return;
11309             }
11310         }
11311
11312         // Well look at that!  It's dead!
11313         synchronized (this) {
11314             if (conn.provider.provider != provider) {
11315                 // But something changed...  good enough.
11316                 return;
11317             }
11318
11319             ProcessRecord proc = conn.provider.proc;
11320             if (proc == null || proc.thread == null) {
11321                 // Seems like the process is already cleaned up.
11322                 return;
11323             }
11324
11325             // As far as we're concerned, this is just like receiving a
11326             // death notification...  just a bit prematurely.
11327             Slog.i(TAG, "Process " + proc.processName + " (pid " + proc.pid
11328                     + ") early provider death");
11329             final long ident = Binder.clearCallingIdentity();
11330             try {
11331                 appDiedLocked(proc);
11332             } finally {
11333                 Binder.restoreCallingIdentity(ident);
11334             }
11335         }
11336     }
11337
11338     @Override
11339     public void appNotRespondingViaProvider(IBinder connection) {
11340         enforceCallingPermission(
11341                 android.Manifest.permission.REMOVE_TASKS, "appNotRespondingViaProvider()");
11342
11343         final ContentProviderConnection conn = (ContentProviderConnection) connection;
11344         if (conn == null) {
11345             Slog.w(TAG, "ContentProviderConnection is null");
11346             return;
11347         }
11348
11349         final ProcessRecord host = conn.provider.proc;
11350         if (host == null) {
11351             Slog.w(TAG, "Failed to find hosting ProcessRecord");
11352             return;
11353         }
11354
11355         mHandler.post(new Runnable() {
11356             @Override
11357             public void run() {
11358                 mAppErrors.appNotResponding(host, null, null, false,
11359                         "ContentProvider not responding");
11360             }
11361         });
11362     }
11363
11364     public final void installSystemProviders() {
11365         List<ProviderInfo> providers;
11366         synchronized (this) {
11367             ProcessRecord app = mProcessNames.get("system", Process.SYSTEM_UID);
11368             providers = generateApplicationProvidersLocked(app);
11369             if (providers != null) {
11370                 for (int i=providers.size()-1; i>=0; i--) {
11371                     ProviderInfo pi = (ProviderInfo)providers.get(i);
11372                     if ((pi.applicationInfo.flags&ApplicationInfo.FLAG_SYSTEM) == 0) {
11373                         Slog.w(TAG, "Not installing system proc provider " + pi.name
11374                                 + ": not system .apk");
11375                         providers.remove(i);
11376                     }
11377                 }
11378             }
11379         }
11380         if (providers != null) {
11381             mSystemThread.installSystemProviders(providers);
11382         }
11383
11384         mCoreSettingsObserver = new CoreSettingsObserver(this);
11385         mFontScaleSettingObserver = new FontScaleSettingObserver();
11386
11387         //mUsageStatsService.monitorPackages();
11388     }
11389
11390     private void startPersistentApps(int matchFlags) {
11391         if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) return;
11392
11393         synchronized (this) {
11394             try {
11395                 final List<ApplicationInfo> apps = AppGlobals.getPackageManager()
11396                         .getPersistentApplications(STOCK_PM_FLAGS | matchFlags).getList();
11397                 for (ApplicationInfo app : apps) {
11398                     if (!"android".equals(app.packageName)) {
11399                         addAppLocked(app, false, null /* ABI override */);
11400                     }
11401                 }
11402             } catch (RemoteException ex) {
11403             }
11404         }
11405     }
11406
11407     /**
11408      * When a user is unlocked, we need to install encryption-unaware providers
11409      * belonging to any running apps.
11410      */
11411     private void installEncryptionUnawareProviders(int userId) {
11412         // We're only interested in providers that are encryption unaware, and
11413         // we don't care about uninstalled apps, since there's no way they're
11414         // running at this point.
11415         final int matchFlags = GET_PROVIDERS | MATCH_DIRECT_BOOT_UNAWARE;
11416
11417         synchronized (this) {
11418             final int NP = mProcessNames.getMap().size();
11419             for (int ip = 0; ip < NP; ip++) {
11420                 final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
11421                 final int NA = apps.size();
11422                 for (int ia = 0; ia < NA; ia++) {
11423                     final ProcessRecord app = apps.valueAt(ia);
11424                     if (app.userId != userId || app.thread == null || app.unlocked) continue;
11425
11426                     final int NG = app.pkgList.size();
11427                     for (int ig = 0; ig < NG; ig++) {
11428                         try {
11429                             final String pkgName = app.pkgList.keyAt(ig);
11430                             final PackageInfo pkgInfo = AppGlobals.getPackageManager()
11431                                     .getPackageInfo(pkgName, matchFlags, userId);
11432                             if (pkgInfo != null && !ArrayUtils.isEmpty(pkgInfo.providers)) {
11433                                 for (ProviderInfo pi : pkgInfo.providers) {
11434                                     // TODO: keep in sync with generateApplicationProvidersLocked
11435                                     final boolean processMatch = Objects.equals(pi.processName,
11436                                             app.processName) || pi.multiprocess;
11437                                     final boolean userMatch = isSingleton(pi.processName,
11438                                             pi.applicationInfo, pi.name, pi.flags)
11439                                                     ? (app.userId == UserHandle.USER_SYSTEM) : true;
11440                                     if (processMatch && userMatch) {
11441                                         Log.v(TAG, "Installing " + pi);
11442                                         app.thread.scheduleInstallProvider(pi);
11443                                     } else {
11444                                         Log.v(TAG, "Skipping " + pi);
11445                                     }
11446                                 }
11447                             }
11448                         } catch (RemoteException ignored) {
11449                         }
11450                     }
11451                 }
11452             }
11453         }
11454     }
11455
11456     /**
11457      * Allows apps to retrieve the MIME type of a URI.
11458      * If an app is in the same user as the ContentProvider, or if it is allowed to interact across
11459      * users, then it does not need permission to access the ContentProvider.
11460      * Either, it needs cross-user uri grants.
11461      *
11462      * CTS tests for this functionality can be run with "runtest cts-appsecurity".
11463      *
11464      * Test cases are at cts/tests/appsecurity-tests/test-apps/UsePermissionDiffCert/
11465      *     src/com/android/cts/usespermissiondiffcertapp/AccessPermissionWithDiffSigTest.java
11466      */
11467     public String getProviderMimeType(Uri uri, int userId) {
11468         enforceNotIsolatedCaller("getProviderMimeType");
11469         final String name = uri.getAuthority();
11470         int callingUid = Binder.getCallingUid();
11471         int callingPid = Binder.getCallingPid();
11472         long ident = 0;
11473         boolean clearedIdentity = false;
11474         synchronized (this) {
11475             userId = mUserController.unsafeConvertIncomingUserLocked(userId);
11476         }
11477         if (canClearIdentity(callingPid, callingUid, userId)) {
11478             clearedIdentity = true;
11479             ident = Binder.clearCallingIdentity();
11480         }
11481         ContentProviderHolder holder = null;
11482         try {
11483             holder = getContentProviderExternalUnchecked(name, null, userId);
11484             if (holder != null) {
11485                 return holder.provider.getType(uri);
11486             }
11487         } catch (RemoteException e) {
11488             Log.w(TAG, "Content provider dead retrieving " + uri, e);
11489             return null;
11490         } catch (Exception e) {
11491             Log.w(TAG, "Exception while determining type of " + uri, e);
11492             return null;
11493         } finally {
11494             // We need to clear the identity to call removeContentProviderExternalUnchecked
11495             if (!clearedIdentity) {
11496                 ident = Binder.clearCallingIdentity();
11497             }
11498             try {
11499                 if (holder != null) {
11500                     removeContentProviderExternalUnchecked(name, null, userId);
11501                 }
11502             } finally {
11503                 Binder.restoreCallingIdentity(ident);
11504             }
11505         }
11506
11507         return null;
11508     }
11509
11510     private boolean canClearIdentity(int callingPid, int callingUid, int userId) {
11511         if (UserHandle.getUserId(callingUid) == userId) {
11512             return true;
11513         }
11514         if (checkComponentPermission(INTERACT_ACROSS_USERS, callingPid,
11515                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED
11516                 || checkComponentPermission(INTERACT_ACROSS_USERS_FULL, callingPid,
11517                 callingUid, -1, true) == PackageManager.PERMISSION_GRANTED) {
11518                 return true;
11519         }
11520         return false;
11521     }
11522
11523     // =========================================================
11524     // GLOBAL MANAGEMENT
11525     // =========================================================
11526
11527     final ProcessRecord newProcessRecordLocked(ApplicationInfo info, String customProcess,
11528             boolean isolated, int isolatedUid) {
11529         String proc = customProcess != null ? customProcess : info.processName;
11530         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
11531         final int userId = UserHandle.getUserId(info.uid);
11532         int uid = info.uid;
11533         if (isolated) {
11534             if (isolatedUid == 0) {
11535                 int stepsLeft = Process.LAST_ISOLATED_UID - Process.FIRST_ISOLATED_UID + 1;
11536                 while (true) {
11537                     if (mNextIsolatedProcessUid < Process.FIRST_ISOLATED_UID
11538                             || mNextIsolatedProcessUid > Process.LAST_ISOLATED_UID) {
11539                         mNextIsolatedProcessUid = Process.FIRST_ISOLATED_UID;
11540                     }
11541                     uid = UserHandle.getUid(userId, mNextIsolatedProcessUid);
11542                     mNextIsolatedProcessUid++;
11543                     if (mIsolatedProcesses.indexOfKey(uid) < 0) {
11544                         // No process for this uid, use it.
11545                         break;
11546                     }
11547                     stepsLeft--;
11548                     if (stepsLeft <= 0) {
11549                         return null;
11550                     }
11551                 }
11552             } else {
11553                 // Special case for startIsolatedProcess (internal only), where
11554                 // the uid of the isolated process is specified by the caller.
11555                 uid = isolatedUid;
11556             }
11557
11558             // Register the isolated UID with this application so BatteryStats knows to
11559             // attribute resource usage to the application.
11560             //
11561             // NOTE: This is done here before addProcessNameLocked, which will tell BatteryStats
11562             // about the process state of the isolated UID *before* it is registered with the
11563             // owning application.
11564             mBatteryStatsService.addIsolatedUid(uid, info.uid);
11565         }
11566         final ProcessRecord r = new ProcessRecord(stats, info, proc, uid);
11567         if (!mBooted && !mBooting
11568                 && userId == UserHandle.USER_SYSTEM
11569                 && (info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11570             r.persistent = true;
11571         }
11572         addProcessNameLocked(r);
11573         return r;
11574     }
11575
11576     final ProcessRecord addAppLocked(ApplicationInfo info, boolean isolated,
11577             String abiOverride) {
11578         ProcessRecord app;
11579         if (!isolated) {
11580             app = getProcessRecordLocked(info.processName, info.uid, true);
11581         } else {
11582             app = null;
11583         }
11584
11585         if (app == null) {
11586             app = newProcessRecordLocked(info, null, isolated, 0);
11587             updateLruProcessLocked(app, false, null);
11588             updateOomAdjLocked();
11589         }
11590
11591         // This package really, really can not be stopped.
11592         try {
11593             AppGlobals.getPackageManager().setPackageStoppedState(
11594                     info.packageName, false, UserHandle.getUserId(app.uid));
11595         } catch (RemoteException e) {
11596         } catch (IllegalArgumentException e) {
11597             Slog.w(TAG, "Failed trying to unstop package "
11598                     + info.packageName + ": " + e);
11599         }
11600
11601         if ((info.flags & PERSISTENT_MASK) == PERSISTENT_MASK) {
11602             app.persistent = true;
11603             app.maxAdj = ProcessList.PERSISTENT_PROC_ADJ;
11604         }
11605         if (app.thread == null && mPersistentStartingProcesses.indexOf(app) < 0) {
11606             mPersistentStartingProcesses.add(app);
11607             startProcessLocked(app, "added application", app.processName, abiOverride,
11608                     null /* entryPoint */, null /* entryPointArgs */);
11609         }
11610
11611         return app;
11612     }
11613
11614     public void unhandledBack() {
11615         enforceCallingPermission(android.Manifest.permission.FORCE_BACK,
11616                 "unhandledBack()");
11617
11618         synchronized(this) {
11619             final long origId = Binder.clearCallingIdentity();
11620             try {
11621                 getFocusedStack().unhandledBackLocked();
11622             } finally {
11623                 Binder.restoreCallingIdentity(origId);
11624             }
11625         }
11626     }
11627
11628     public ParcelFileDescriptor openContentUri(Uri uri) throws RemoteException {
11629         enforceNotIsolatedCaller("openContentUri");
11630         final int userId = UserHandle.getCallingUserId();
11631         String name = uri.getAuthority();
11632         ContentProviderHolder cph = getContentProviderExternalUnchecked(name, null, userId);
11633         ParcelFileDescriptor pfd = null;
11634         if (cph != null) {
11635             // We record the binder invoker's uid in thread-local storage before
11636             // going to the content provider to open the file.  Later, in the code
11637             // that handles all permissions checks, we look for this uid and use
11638             // that rather than the Activity Manager's own uid.  The effect is that
11639             // we do the check against the caller's permissions even though it looks
11640             // to the content provider like the Activity Manager itself is making
11641             // the request.
11642             Binder token = new Binder();
11643             sCallerIdentity.set(new Identity(
11644                     token, Binder.getCallingPid(), Binder.getCallingUid()));
11645             try {
11646                 pfd = cph.provider.openFile(null, uri, "r", null, token);
11647             } catch (FileNotFoundException e) {
11648                 // do nothing; pfd will be returned null
11649             } finally {
11650                 // Ensure that whatever happens, we clean up the identity state
11651                 sCallerIdentity.remove();
11652                 // Ensure we're done with the provider.
11653                 removeContentProviderExternalUnchecked(name, null, userId);
11654             }
11655         } else {
11656             Slog.d(TAG, "Failed to get provider for authority '" + name + "'");
11657         }
11658         return pfd;
11659     }
11660
11661     // Actually is sleeping or shutting down or whatever else in the future
11662     // is an inactive state.
11663     boolean isSleepingOrShuttingDownLocked() {
11664         return isSleepingLocked() || mShuttingDown;
11665     }
11666
11667     boolean isShuttingDownLocked() {
11668         return mShuttingDown;
11669     }
11670
11671     boolean isSleepingLocked() {
11672         return mSleeping;
11673     }
11674
11675     void onWakefulnessChanged(int wakefulness) {
11676         synchronized(this) {
11677             mWakefulness = wakefulness;
11678             updateSleepIfNeededLocked();
11679         }
11680     }
11681
11682     void finishRunningVoiceLocked() {
11683         if (mRunningVoice != null) {
11684             mRunningVoice = null;
11685             mVoiceWakeLock.release();
11686             updateSleepIfNeededLocked();
11687         }
11688     }
11689
11690     void startTimeTrackingFocusedActivityLocked() {
11691         if (!mSleeping && mCurAppTimeTracker != null && mFocusedActivity != null) {
11692             mCurAppTimeTracker.start(mFocusedActivity.packageName);
11693         }
11694     }
11695
11696     void updateSleepIfNeededLocked() {
11697         if (mSleeping && !shouldSleepLocked()) {
11698             mSleeping = false;
11699             startTimeTrackingFocusedActivityLocked();
11700             mTopProcessState = ActivityManager.PROCESS_STATE_TOP;
11701             mStackSupervisor.comeOutOfSleepIfNeededLocked();
11702             updateOomAdjLocked();
11703         } else if (!mSleeping && shouldSleepLocked()) {
11704             mSleeping = true;
11705             if (mCurAppTimeTracker != null) {
11706                 mCurAppTimeTracker.stop();
11707             }
11708             mTopProcessState = ActivityManager.PROCESS_STATE_TOP_SLEEPING;
11709             mStackSupervisor.goingToSleepLocked();
11710             updateOomAdjLocked();
11711
11712             // Initialize the wake times of all processes.
11713             checkExcessivePowerUsageLocked(false);
11714             mHandler.removeMessages(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11715             Message nmsg = mHandler.obtainMessage(CHECK_EXCESSIVE_WAKE_LOCKS_MSG);
11716             mHandler.sendMessageDelayed(nmsg, POWER_CHECK_DELAY);
11717         }
11718     }
11719
11720     private boolean shouldSleepLocked() {
11721         // Resume applications while running a voice interactor.
11722         if (mRunningVoice != null) {
11723             return false;
11724         }
11725
11726         // TODO: Transform the lock screen state into a sleep token instead.
11727         switch (mWakefulness) {
11728             case PowerManagerInternal.WAKEFULNESS_AWAKE:
11729             case PowerManagerInternal.WAKEFULNESS_DREAMING:
11730             case PowerManagerInternal.WAKEFULNESS_DOZING:
11731                 // Pause applications whenever the lock screen is shown or any sleep
11732                 // tokens have been acquired.
11733                 return (mLockScreenShown != LOCK_SCREEN_HIDDEN || !mSleepTokens.isEmpty());
11734             case PowerManagerInternal.WAKEFULNESS_ASLEEP:
11735             default:
11736                 // If we're asleep then pause applications unconditionally.
11737                 return true;
11738         }
11739     }
11740
11741     /** Pokes the task persister. */
11742     void notifyTaskPersisterLocked(TaskRecord task, boolean flush) {
11743         mRecentTasks.notifyTaskPersisterLocked(task, flush);
11744     }
11745
11746     /** Notifies all listeners when the task stack has changed. */
11747     void notifyTaskStackChangedLocked() {
11748         mHandler.sendEmptyMessage(LOG_STACK_STATE);
11749         mHandler.removeMessages(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11750         Message nmsg = mHandler.obtainMessage(NOTIFY_TASK_STACK_CHANGE_LISTENERS_MSG);
11751         mHandler.sendMessageDelayed(nmsg, NOTIFY_TASK_STACK_CHANGE_LISTENERS_DELAY);
11752     }
11753
11754     /** Notifies all listeners when an Activity is pinned. */
11755     void notifyActivityPinnedLocked() {
11756         mHandler.removeMessages(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG);
11757         mHandler.obtainMessage(NOTIFY_ACTIVITY_PINNED_LISTENERS_MSG).sendToTarget();
11758     }
11759
11760     /**
11761      * Notifies all listeners when an attempt was made to start an an activity that is already
11762      * running in the pinned stack and the activity was not actually started, but the task is
11763      * either brought to the front or a new Intent is delivered to it.
11764      */
11765     void notifyPinnedActivityRestartAttemptLocked() {
11766         mHandler.removeMessages(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG);
11767         mHandler.obtainMessage(NOTIFY_PINNED_ACTIVITY_RESTART_ATTEMPT_LISTENERS_MSG).sendToTarget();
11768     }
11769
11770     /** Notifies all listeners when the pinned stack animation ends. */
11771     @Override
11772     public void notifyPinnedStackAnimationEnded() {
11773         synchronized (this) {
11774             mHandler.removeMessages(NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG);
11775             mHandler.obtainMessage(
11776                     NOTIFY_PINNED_STACK_ANIMATION_ENDED_LISTENERS_MSG).sendToTarget();
11777         }
11778     }
11779
11780     @Override
11781     public void notifyCleartextNetwork(int uid, byte[] firstPacket) {
11782         mHandler.obtainMessage(NOTIFY_CLEARTEXT_NETWORK_MSG, uid, 0, firstPacket).sendToTarget();
11783     }
11784
11785     @Override
11786     public boolean shutdown(int timeout) {
11787         if (checkCallingPermission(android.Manifest.permission.SHUTDOWN)
11788                 != PackageManager.PERMISSION_GRANTED) {
11789             throw new SecurityException("Requires permission "
11790                     + android.Manifest.permission.SHUTDOWN);
11791         }
11792
11793         boolean timedout = false;
11794
11795         synchronized(this) {
11796             mShuttingDown = true;
11797             updateEventDispatchingLocked();
11798             timedout = mStackSupervisor.shutdownLocked(timeout);
11799         }
11800
11801         mAppOpsService.shutdown();
11802         if (mUsageStatsService != null) {
11803             mUsageStatsService.prepareShutdown();
11804         }
11805         mBatteryStatsService.shutdown();
11806         synchronized (this) {
11807             mProcessStats.shutdownLocked();
11808             notifyTaskPersisterLocked(null, true);
11809         }
11810
11811         return timedout;
11812     }
11813
11814     public final void activitySlept(IBinder token) {
11815         if (DEBUG_ALL) Slog.v(TAG, "Activity slept: token=" + token);
11816
11817         final long origId = Binder.clearCallingIdentity();
11818
11819         synchronized (this) {
11820             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
11821             if (r != null) {
11822                 mStackSupervisor.activitySleptLocked(r);
11823             }
11824         }
11825
11826         Binder.restoreCallingIdentity(origId);
11827     }
11828
11829     private String lockScreenShownToString() {
11830         switch (mLockScreenShown) {
11831             case LOCK_SCREEN_HIDDEN: return "LOCK_SCREEN_HIDDEN";
11832             case LOCK_SCREEN_LEAVING: return "LOCK_SCREEN_LEAVING";
11833             case LOCK_SCREEN_SHOWN: return "LOCK_SCREEN_SHOWN";
11834             default: return "Unknown=" + mLockScreenShown;
11835         }
11836     }
11837
11838     void logLockScreen(String msg) {
11839         if (DEBUG_LOCKSCREEN) Slog.d(TAG_LOCKSCREEN, Debug.getCallers(2) + ":" + msg
11840                 + " mLockScreenShown=" + lockScreenShownToString() + " mWakefulness="
11841                 + PowerManagerInternal.wakefulnessToString(mWakefulness)
11842                 + " mSleeping=" + mSleeping);
11843     }
11844
11845     void startRunningVoiceLocked(IVoiceInteractionSession session, int targetUid) {
11846         Slog.d(TAG, "<<<  startRunningVoiceLocked()");
11847         mVoiceWakeLock.setWorkSource(new WorkSource(targetUid));
11848         if (mRunningVoice == null || mRunningVoice.asBinder() != session.asBinder()) {
11849             boolean wasRunningVoice = mRunningVoice != null;
11850             mRunningVoice = session;
11851             if (!wasRunningVoice) {
11852                 mVoiceWakeLock.acquire();
11853                 updateSleepIfNeededLocked();
11854             }
11855         }
11856     }
11857
11858     private void updateEventDispatchingLocked() {
11859         mWindowManager.setEventDispatching(mBooted && !mShuttingDown);
11860     }
11861
11862     public void setLockScreenShown(boolean showing, boolean occluded) {
11863         if (checkCallingPermission(android.Manifest.permission.DEVICE_POWER)
11864                 != PackageManager.PERMISSION_GRANTED) {
11865             throw new SecurityException("Requires permission "
11866                     + android.Manifest.permission.DEVICE_POWER);
11867         }
11868
11869         synchronized(this) {
11870             long ident = Binder.clearCallingIdentity();
11871             try {
11872                 if (DEBUG_LOCKSCREEN) logLockScreen(" showing=" + showing + " occluded=" + occluded);
11873                 mLockScreenShown = (showing && !occluded) ? LOCK_SCREEN_SHOWN : LOCK_SCREEN_HIDDEN;
11874                 if (showing && occluded) {
11875                     // The lock screen is currently showing, but is occluded by a window that can
11876                     // show on top of the lock screen. In this can we want to dismiss the docked
11877                     // stack since it will be complicated/risky to try to put the activity on top
11878                     // of the lock screen in the right fullscreen configuration.
11879                     mStackSupervisor.moveTasksToFullscreenStackLocked(DOCKED_STACK_ID,
11880                             mStackSupervisor.mFocusedStack.getStackId() == DOCKED_STACK_ID);
11881                 }
11882
11883                 updateSleepIfNeededLocked();
11884             } finally {
11885                 Binder.restoreCallingIdentity(ident);
11886             }
11887         }
11888     }
11889
11890     @Override
11891     public void notifyLockedProfile(@UserIdInt int userId) {
11892         try {
11893             if (!AppGlobals.getPackageManager().isUidPrivileged(Binder.getCallingUid())) {
11894                 throw new SecurityException("Only privileged app can call notifyLockedProfile");
11895             }
11896         } catch (RemoteException ex) {
11897             throw new SecurityException("Fail to check is caller a privileged app", ex);
11898         }
11899
11900         synchronized (this) {
11901             if (mStackSupervisor.isUserLockedProfile(userId)) {
11902                 final long ident = Binder.clearCallingIdentity();
11903                 try {
11904                     final int currentUserId = mUserController.getCurrentUserIdLocked();
11905
11906                     // Drop locked freeform tasks out into the fullscreen stack.
11907                     // TODO: Redact the tasks in place. It's much better to keep them on the screen
11908                     //       where they were before, but in an obscured state.
11909                     mStackSupervisor.moveProfileTasksFromFreeformToFullscreenStackLocked(userId);
11910
11911                     if (mUserController.isLockScreenDisabled(currentUserId)) {
11912                         // If there is no device lock, we will show the profile's credential page.
11913                         mActivityStarter.showConfirmDeviceCredential(userId);
11914                     } else {
11915                         // Showing launcher to avoid user entering credential twice.
11916                         startHomeActivityLocked(currentUserId, "notifyLockedProfile");
11917                     }
11918                 } finally {
11919                     Binder.restoreCallingIdentity(ident);
11920                 }
11921             }
11922         }
11923     }
11924
11925     @Override
11926     public void startConfirmDeviceCredentialIntent(Intent intent) {
11927         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "startConfirmDeviceCredentialIntent");
11928         synchronized (this) {
11929             final long ident = Binder.clearCallingIdentity();
11930             try {
11931                 mActivityStarter.startConfirmCredentialIntent(intent);
11932             } finally {
11933                 Binder.restoreCallingIdentity(ident);
11934             }
11935         }
11936     }
11937
11938     @Override
11939     public void stopAppSwitches() {
11940         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11941                 != PackageManager.PERMISSION_GRANTED) {
11942             throw new SecurityException("viewquires permission "
11943                     + android.Manifest.permission.STOP_APP_SWITCHES);
11944         }
11945
11946         synchronized(this) {
11947             mAppSwitchesAllowedTime = SystemClock.uptimeMillis()
11948                     + APP_SWITCH_DELAY_TIME;
11949             mDidAppSwitch = false;
11950             mHandler.removeMessages(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11951             Message msg = mHandler.obtainMessage(DO_PENDING_ACTIVITY_LAUNCHES_MSG);
11952             mHandler.sendMessageDelayed(msg, APP_SWITCH_DELAY_TIME);
11953         }
11954     }
11955
11956     public void resumeAppSwitches() {
11957         if (checkCallingPermission(android.Manifest.permission.STOP_APP_SWITCHES)
11958                 != PackageManager.PERMISSION_GRANTED) {
11959             throw new SecurityException("Requires permission "
11960                     + android.Manifest.permission.STOP_APP_SWITCHES);
11961         }
11962
11963         synchronized(this) {
11964             // Note that we don't execute any pending app switches... we will
11965             // let those wait until either the timeout, or the next start
11966             // activity request.
11967             mAppSwitchesAllowedTime = 0;
11968         }
11969     }
11970
11971     boolean checkAppSwitchAllowedLocked(int sourcePid, int sourceUid,
11972             int callingPid, int callingUid, String name) {
11973         if (mAppSwitchesAllowedTime < SystemClock.uptimeMillis()) {
11974             return true;
11975         }
11976
11977         int perm = checkComponentPermission(
11978                 android.Manifest.permission.STOP_APP_SWITCHES, sourcePid,
11979                 sourceUid, -1, true);
11980         if (perm == PackageManager.PERMISSION_GRANTED) {
11981             return true;
11982         }
11983
11984         // If the actual IPC caller is different from the logical source, then
11985         // also see if they are allowed to control app switches.
11986         if (callingUid != -1 && callingUid != sourceUid) {
11987             perm = checkComponentPermission(
11988                     android.Manifest.permission.STOP_APP_SWITCHES, callingPid,
11989                     callingUid, -1, true);
11990             if (perm == PackageManager.PERMISSION_GRANTED) {
11991                 return true;
11992             }
11993         }
11994
11995         Slog.w(TAG, name + " request from " + sourceUid + " stopped");
11996         return false;
11997     }
11998
11999     public void setDebugApp(String packageName, boolean waitForDebugger,
12000             boolean persistent) {
12001         enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
12002                 "setDebugApp()");
12003
12004         long ident = Binder.clearCallingIdentity();
12005         try {
12006             // Note that this is not really thread safe if there are multiple
12007             // callers into it at the same time, but that's not a situation we
12008             // care about.
12009             if (persistent) {
12010                 final ContentResolver resolver = mContext.getContentResolver();
12011                 Settings.Global.putString(
12012                     resolver, Settings.Global.DEBUG_APP,
12013                     packageName);
12014                 Settings.Global.putInt(
12015                     resolver, Settings.Global.WAIT_FOR_DEBUGGER,
12016                     waitForDebugger ? 1 : 0);
12017             }
12018
12019             synchronized (this) {
12020                 if (!persistent) {
12021                     mOrigDebugApp = mDebugApp;
12022                     mOrigWaitForDebugger = mWaitForDebugger;
12023                 }
12024                 mDebugApp = packageName;
12025                 mWaitForDebugger = waitForDebugger;
12026                 mDebugTransient = !persistent;
12027                 if (packageName != null) {
12028                     forceStopPackageLocked(packageName, -1, false, false, true, true,
12029                             false, UserHandle.USER_ALL, "set debug app");
12030                 }
12031             }
12032         } finally {
12033             Binder.restoreCallingIdentity(ident);
12034         }
12035     }
12036
12037     void setTrackAllocationApp(ApplicationInfo app, String processName) {
12038         synchronized (this) {
12039             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12040             if (!isDebuggable) {
12041                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12042                     throw new SecurityException("Process not debuggable: " + app.packageName);
12043                 }
12044             }
12045
12046             mTrackAllocationApp = processName;
12047         }
12048     }
12049
12050     void setProfileApp(ApplicationInfo app, String processName, ProfilerInfo profilerInfo) {
12051         synchronized (this) {
12052             boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12053             if (!isDebuggable) {
12054                 if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12055                     throw new SecurityException("Process not debuggable: " + app.packageName);
12056                 }
12057             }
12058             mProfileApp = processName;
12059             mProfileFile = profilerInfo.profileFile;
12060             if (mProfileFd != null) {
12061                 try {
12062                     mProfileFd.close();
12063                 } catch (IOException e) {
12064                 }
12065                 mProfileFd = null;
12066             }
12067             mProfileFd = profilerInfo.profileFd;
12068             mSamplingInterval = profilerInfo.samplingInterval;
12069             mAutoStopProfiler = profilerInfo.autoStopProfiler;
12070             mProfileType = 0;
12071         }
12072     }
12073
12074     void setNativeDebuggingAppLocked(ApplicationInfo app, String processName) {
12075         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
12076         if (!isDebuggable) {
12077             if ((app.flags & ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
12078                 throw new SecurityException("Process not debuggable: " + app.packageName);
12079             }
12080         }
12081         mNativeDebuggingApp = processName;
12082     }
12083
12084     @Override
12085     public void setAlwaysFinish(boolean enabled) {
12086         enforceCallingPermission(android.Manifest.permission.SET_ALWAYS_FINISH,
12087                 "setAlwaysFinish()");
12088
12089         long ident = Binder.clearCallingIdentity();
12090         try {
12091             Settings.Global.putInt(
12092                     mContext.getContentResolver(),
12093                     Settings.Global.ALWAYS_FINISH_ACTIVITIES, enabled ? 1 : 0);
12094
12095             synchronized (this) {
12096                 mAlwaysFinishActivities = enabled;
12097             }
12098         } finally {
12099             Binder.restoreCallingIdentity(ident);
12100         }
12101     }
12102
12103     @Override
12104     public void setLenientBackgroundCheck(boolean enabled) {
12105         enforceCallingPermission(android.Manifest.permission.SET_PROCESS_LIMIT,
12106                 "setLenientBackgroundCheck()");
12107
12108         long ident = Binder.clearCallingIdentity();
12109         try {
12110             Settings.Global.putInt(
12111                     mContext.getContentResolver(),
12112                     Settings.Global.LENIENT_BACKGROUND_CHECK, enabled ? 1 : 0);
12113
12114             synchronized (this) {
12115                 mLenientBackgroundCheck = enabled;
12116             }
12117         } finally {
12118             Binder.restoreCallingIdentity(ident);
12119         }
12120     }
12121
12122     @Override
12123     public void setActivityController(IActivityController controller, boolean imAMonkey) {
12124         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12125                 "setActivityController()");
12126         synchronized (this) {
12127             mController = controller;
12128             mControllerIsAMonkey = imAMonkey;
12129             Watchdog.getInstance().setActivityController(controller);
12130         }
12131     }
12132
12133     @Override
12134     public void setUserIsMonkey(boolean userIsMonkey) {
12135         synchronized (this) {
12136             synchronized (mPidsSelfLocked) {
12137                 final int callingPid = Binder.getCallingPid();
12138                 ProcessRecord precessRecord = mPidsSelfLocked.get(callingPid);
12139                 if (precessRecord == null) {
12140                     throw new SecurityException("Unknown process: " + callingPid);
12141                 }
12142                 if (precessRecord.instrumentationUiAutomationConnection  == null) {
12143                     throw new SecurityException("Only an instrumentation process "
12144                             + "with a UiAutomation can call setUserIsMonkey");
12145                 }
12146             }
12147             mUserIsMonkey = userIsMonkey;
12148         }
12149     }
12150
12151     @Override
12152     public boolean isUserAMonkey() {
12153         synchronized (this) {
12154             // If there is a controller also implies the user is a monkey.
12155             return (mUserIsMonkey || (mController != null && mControllerIsAMonkey));
12156         }
12157     }
12158
12159     public void requestBugReport(int bugreportType) {
12160         String service = null;
12161         switch (bugreportType) {
12162             case ActivityManager.BUGREPORT_OPTION_FULL:
12163                 service = "bugreport";
12164                 break;
12165             case ActivityManager.BUGREPORT_OPTION_INTERACTIVE:
12166                 service = "bugreportplus";
12167                 break;
12168             case ActivityManager.BUGREPORT_OPTION_REMOTE:
12169                 service = "bugreportremote";
12170                 break;
12171             case ActivityManager.BUGREPORT_OPTION_WEAR:
12172                 service = "bugreportwear";
12173                 break;
12174         }
12175         if (service == null) {
12176             throw new IllegalArgumentException("Provided bugreport type is not correct, value: "
12177                     + bugreportType);
12178         }
12179         enforceCallingPermission(android.Manifest.permission.DUMP, "requestBugReport");
12180         SystemProperties.set("ctl.start", service);
12181     }
12182
12183     public static long getInputDispatchingTimeoutLocked(ActivityRecord r) {
12184         return r != null ? getInputDispatchingTimeoutLocked(r.app) : KEY_DISPATCHING_TIMEOUT;
12185     }
12186
12187     public static long getInputDispatchingTimeoutLocked(ProcessRecord r) {
12188         if (r != null && (r.instrumentationClass != null || r.usingWrapper)) {
12189             return INSTRUMENTATION_KEY_DISPATCHING_TIMEOUT;
12190         }
12191         return KEY_DISPATCHING_TIMEOUT;
12192     }
12193
12194     @Override
12195     public long inputDispatchingTimedOut(int pid, final boolean aboveSystem, String reason) {
12196         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12197                 != PackageManager.PERMISSION_GRANTED) {
12198             throw new SecurityException("Requires permission "
12199                     + android.Manifest.permission.FILTER_EVENTS);
12200         }
12201         ProcessRecord proc;
12202         long timeout;
12203         synchronized (this) {
12204             synchronized (mPidsSelfLocked) {
12205                 proc = mPidsSelfLocked.get(pid);
12206             }
12207             timeout = getInputDispatchingTimeoutLocked(proc);
12208         }
12209
12210         if (!inputDispatchingTimedOut(proc, null, null, aboveSystem, reason)) {
12211             return -1;
12212         }
12213
12214         return timeout;
12215     }
12216
12217     /**
12218      * Handle input dispatching timeouts.
12219      * Returns whether input dispatching should be aborted or not.
12220      */
12221     public boolean inputDispatchingTimedOut(final ProcessRecord proc,
12222             final ActivityRecord activity, final ActivityRecord parent,
12223             final boolean aboveSystem, String reason) {
12224         if (checkCallingPermission(android.Manifest.permission.FILTER_EVENTS)
12225                 != PackageManager.PERMISSION_GRANTED) {
12226             throw new SecurityException("Requires permission "
12227                     + android.Manifest.permission.FILTER_EVENTS);
12228         }
12229
12230         final String annotation;
12231         if (reason == null) {
12232             annotation = "Input dispatching timed out";
12233         } else {
12234             annotation = "Input dispatching timed out (" + reason + ")";
12235         }
12236
12237         if (proc != null) {
12238             synchronized (this) {
12239                 if (proc.debugging) {
12240                     return false;
12241                 }
12242
12243                 if (mDidDexOpt) {
12244                     // Give more time since we were dexopting.
12245                     mDidDexOpt = false;
12246                     return false;
12247                 }
12248
12249                 if (proc.instrumentationClass != null) {
12250                     Bundle info = new Bundle();
12251                     info.putString("shortMsg", "keyDispatchingTimedOut");
12252                     info.putString("longMsg", annotation);
12253                     finishInstrumentationLocked(proc, Activity.RESULT_CANCELED, info);
12254                     return true;
12255                 }
12256             }
12257             mHandler.post(new Runnable() {
12258                 @Override
12259                 public void run() {
12260                     mAppErrors.appNotResponding(proc, activity, parent, aboveSystem, annotation);
12261                 }
12262             });
12263         }
12264
12265         return true;
12266     }
12267
12268     @Override
12269     public Bundle getAssistContextExtras(int requestType) {
12270         PendingAssistExtras pae = enqueueAssistContext(requestType, null, null, null,
12271                 null, null, true /* focused */, true /* newSessionId */,
12272                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_TIMEOUT);
12273         if (pae == null) {
12274             return null;
12275         }
12276         synchronized (pae) {
12277             while (!pae.haveResult) {
12278                 try {
12279                     pae.wait();
12280                 } catch (InterruptedException e) {
12281                 }
12282             }
12283         }
12284         synchronized (this) {
12285             buildAssistBundleLocked(pae, pae.result);
12286             mPendingAssistExtras.remove(pae);
12287             mUiHandler.removeCallbacks(pae);
12288         }
12289         return pae.extras;
12290     }
12291
12292     @Override
12293     public boolean isAssistDataAllowedOnCurrentActivity() {
12294         int userId;
12295         synchronized (this) {
12296             userId = mUserController.getCurrentUserIdLocked();
12297             ActivityRecord activity = getFocusedStack().topActivity();
12298             if (activity == null) {
12299                 return false;
12300             }
12301             userId = activity.userId;
12302         }
12303         DevicePolicyManager dpm = (DevicePolicyManager) mContext.getSystemService(
12304                 Context.DEVICE_POLICY_SERVICE);
12305         return (dpm == null) || (!dpm.getScreenCaptureDisabled(null, userId));
12306     }
12307
12308     @Override
12309     public boolean showAssistFromActivity(IBinder token, Bundle args) {
12310         long ident = Binder.clearCallingIdentity();
12311         try {
12312             synchronized (this) {
12313                 ActivityRecord caller = ActivityRecord.forTokenLocked(token);
12314                 ActivityRecord top = getFocusedStack().topActivity();
12315                 if (top != caller) {
12316                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12317                             + " is not current top " + top);
12318                     return false;
12319                 }
12320                 if (!top.nowVisible) {
12321                     Slog.w(TAG, "showAssistFromActivity failed: caller " + caller
12322                             + " is not visible");
12323                     return false;
12324                 }
12325             }
12326             AssistUtils utils = new AssistUtils(mContext);
12327             return utils.showSessionForActiveService(args,
12328                     VoiceInteractionSession.SHOW_SOURCE_APPLICATION, null, token);
12329         } finally {
12330             Binder.restoreCallingIdentity(ident);
12331         }
12332     }
12333
12334     @Override
12335     public boolean requestAssistContextExtras(int requestType, IResultReceiver receiver,
12336             Bundle receiverExtras,
12337             IBinder activityToken, boolean focused, boolean newSessionId) {
12338         return enqueueAssistContext(requestType, null, null, receiver, receiverExtras,
12339                 activityToken, focused, newSessionId,
12340                 UserHandle.getCallingUserId(), null, PENDING_ASSIST_EXTRAS_LONG_TIMEOUT)
12341                 != null;
12342     }
12343
12344     private PendingAssistExtras enqueueAssistContext(int requestType, Intent intent, String hint,
12345             IResultReceiver receiver, Bundle receiverExtras, IBinder activityToken,
12346             boolean focused, boolean newSessionId, int userHandle, Bundle args, long timeout) {
12347         enforceCallingPermission(android.Manifest.permission.GET_TOP_ACTIVITY_INFO,
12348                 "enqueueAssistContext()");
12349         synchronized (this) {
12350             ActivityRecord activity = getFocusedStack().topActivity();
12351             if (activity == null) {
12352                 Slog.w(TAG, "getAssistContextExtras failed: no top activity");
12353                 return null;
12354             }
12355             if (activity.app == null || activity.app.thread == null) {
12356                 Slog.w(TAG, "getAssistContextExtras failed: no process for " + activity);
12357                 return null;
12358             }
12359             if (focused) {
12360                 if (activityToken != null) {
12361                     ActivityRecord caller = ActivityRecord.forTokenLocked(activityToken);
12362                     if (activity != caller) {
12363                         Slog.w(TAG, "enqueueAssistContext failed: caller " + caller
12364                                 + " is not current top " + activity);
12365                         return null;
12366                     }
12367                 }
12368             } else {
12369                 activity = ActivityRecord.forTokenLocked(activityToken);
12370                 if (activity == null) {
12371                     Slog.w(TAG, "enqueueAssistContext failed: activity for token=" + activityToken
12372                             + " couldn't be found");
12373                     return null;
12374                 }
12375             }
12376
12377             PendingAssistExtras pae;
12378             Bundle extras = new Bundle();
12379             if (args != null) {
12380                 extras.putAll(args);
12381             }
12382             extras.putString(Intent.EXTRA_ASSIST_PACKAGE, activity.packageName);
12383             extras.putInt(Intent.EXTRA_ASSIST_UID, activity.app.uid);
12384             pae = new PendingAssistExtras(activity, extras, intent, hint, receiver, receiverExtras,
12385                     userHandle);
12386             // Increment the sessionId if necessary
12387             if (newSessionId) {
12388                 mViSessionId++;
12389             }
12390             try {
12391                 activity.app.thread.requestAssistContextExtras(activity.appToken, pae,
12392                         requestType, mViSessionId);
12393                 mPendingAssistExtras.add(pae);
12394                 mUiHandler.postDelayed(pae, timeout);
12395             } catch (RemoteException e) {
12396                 Slog.w(TAG, "getAssistContextExtras failed: crash calling " + activity);
12397                 return null;
12398             }
12399             return pae;
12400         }
12401     }
12402
12403     void pendingAssistExtrasTimedOut(PendingAssistExtras pae) {
12404         IResultReceiver receiver;
12405         synchronized (this) {
12406             mPendingAssistExtras.remove(pae);
12407             receiver = pae.receiver;
12408         }
12409         if (receiver != null) {
12410             // Caller wants result sent back to them.
12411             Bundle sendBundle = new Bundle();
12412             // At least return the receiver extras
12413             sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12414                     pae.receiverExtras);
12415             try {
12416                 pae.receiver.send(0, sendBundle);
12417             } catch (RemoteException e) {
12418             }
12419         }
12420     }
12421
12422     private void buildAssistBundleLocked(PendingAssistExtras pae, Bundle result) {
12423         if (result != null) {
12424             pae.extras.putBundle(Intent.EXTRA_ASSIST_CONTEXT, result);
12425         }
12426         if (pae.hint != null) {
12427             pae.extras.putBoolean(pae.hint, true);
12428         }
12429     }
12430
12431     public void reportAssistContextExtras(IBinder token, Bundle extras, AssistStructure structure,
12432             AssistContent content, Uri referrer) {
12433         PendingAssistExtras pae = (PendingAssistExtras)token;
12434         synchronized (pae) {
12435             pae.result = extras;
12436             pae.structure = structure;
12437             pae.content = content;
12438             if (referrer != null) {
12439                 pae.extras.putParcelable(Intent.EXTRA_REFERRER, referrer);
12440             }
12441             pae.haveResult = true;
12442             pae.notifyAll();
12443             if (pae.intent == null && pae.receiver == null) {
12444                 // Caller is just waiting for the result.
12445                 return;
12446             }
12447         }
12448
12449         // We are now ready to launch the assist activity.
12450         IResultReceiver sendReceiver = null;
12451         Bundle sendBundle = null;
12452         synchronized (this) {
12453             buildAssistBundleLocked(pae, extras);
12454             boolean exists = mPendingAssistExtras.remove(pae);
12455             mUiHandler.removeCallbacks(pae);
12456             if (!exists) {
12457                 // Timed out.
12458                 return;
12459             }
12460             if ((sendReceiver=pae.receiver) != null) {
12461                 // Caller wants result sent back to them.
12462                 sendBundle = new Bundle();
12463                 sendBundle.putBundle(VoiceInteractionSession.KEY_DATA, pae.extras);
12464                 sendBundle.putParcelable(VoiceInteractionSession.KEY_STRUCTURE, pae.structure);
12465                 sendBundle.putParcelable(VoiceInteractionSession.KEY_CONTENT, pae.content);
12466                 sendBundle.putBundle(VoiceInteractionSession.KEY_RECEIVER_EXTRAS,
12467                         pae.receiverExtras);
12468             }
12469         }
12470         if (sendReceiver != null) {
12471             try {
12472                 sendReceiver.send(0, sendBundle);
12473             } catch (RemoteException e) {
12474             }
12475             return;
12476         }
12477
12478         long ident = Binder.clearCallingIdentity();
12479         try {
12480             pae.intent.replaceExtras(pae.extras);
12481             pae.intent.setFlags(Intent.FLAG_ACTIVITY_NEW_TASK
12482                     | Intent.FLAG_ACTIVITY_SINGLE_TOP
12483                     | Intent.FLAG_ACTIVITY_CLEAR_TOP);
12484             closeSystemDialogs("assist");
12485             try {
12486                 mContext.startActivityAsUser(pae.intent, new UserHandle(pae.userHandle));
12487             } catch (ActivityNotFoundException e) {
12488                 Slog.w(TAG, "No activity to handle assist action.", e);
12489             }
12490         } finally {
12491             Binder.restoreCallingIdentity(ident);
12492         }
12493     }
12494
12495     public boolean launchAssistIntent(Intent intent, int requestType, String hint, int userHandle,
12496             Bundle args) {
12497         return enqueueAssistContext(requestType, intent, hint, null, null, null,
12498                 true /* focused */, true /* newSessionId */,
12499                 userHandle, args, PENDING_ASSIST_EXTRAS_TIMEOUT) != null;
12500     }
12501
12502     public void registerProcessObserver(IProcessObserver observer) {
12503         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12504                 "registerProcessObserver()");
12505         synchronized (this) {
12506             mProcessObservers.register(observer);
12507         }
12508     }
12509
12510     @Override
12511     public void unregisterProcessObserver(IProcessObserver observer) {
12512         synchronized (this) {
12513             mProcessObservers.unregister(observer);
12514         }
12515     }
12516
12517     @Override
12518     public void registerUidObserver(IUidObserver observer, int which) {
12519         enforceCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER,
12520                 "registerUidObserver()");
12521         synchronized (this) {
12522             mUidObservers.register(observer, which);
12523         }
12524     }
12525
12526     @Override
12527     public void unregisterUidObserver(IUidObserver observer) {
12528         synchronized (this) {
12529             mUidObservers.unregister(observer);
12530         }
12531     }
12532
12533     @Override
12534     public boolean convertFromTranslucent(IBinder token) {
12535         final long origId = Binder.clearCallingIdentity();
12536         try {
12537             synchronized (this) {
12538                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12539                 if (r == null) {
12540                     return false;
12541                 }
12542                 final boolean translucentChanged = r.changeWindowTranslucency(true);
12543                 if (translucentChanged) {
12544                     r.task.stack.releaseBackgroundResources(r);
12545                     mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12546                 }
12547                 mWindowManager.setAppFullscreen(token, true);
12548                 return translucentChanged;
12549             }
12550         } finally {
12551             Binder.restoreCallingIdentity(origId);
12552         }
12553     }
12554
12555     @Override
12556     public boolean convertToTranslucent(IBinder token, ActivityOptions options) {
12557         final long origId = Binder.clearCallingIdentity();
12558         try {
12559             synchronized (this) {
12560                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12561                 if (r == null) {
12562                     return false;
12563                 }
12564                 int index = r.task.mActivities.lastIndexOf(r);
12565                 if (index > 0) {
12566                     ActivityRecord under = r.task.mActivities.get(index - 1);
12567                     under.returningOptions = options;
12568                 }
12569                 final boolean translucentChanged = r.changeWindowTranslucency(false);
12570                 if (translucentChanged) {
12571                     r.task.stack.convertActivityToTranslucent(r);
12572                 }
12573                 mStackSupervisor.ensureActivitiesVisibleLocked(null, 0, !PRESERVE_WINDOWS);
12574                 mWindowManager.setAppFullscreen(token, false);
12575                 return translucentChanged;
12576             }
12577         } finally {
12578             Binder.restoreCallingIdentity(origId);
12579         }
12580     }
12581
12582     @Override
12583     public boolean requestVisibleBehind(IBinder token, boolean visible) {
12584         final long origId = Binder.clearCallingIdentity();
12585         try {
12586             synchronized (this) {
12587                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12588                 if (r != null) {
12589                     return mStackSupervisor.requestVisibleBehindLocked(r, visible);
12590                 }
12591             }
12592             return false;
12593         } finally {
12594             Binder.restoreCallingIdentity(origId);
12595         }
12596     }
12597
12598     @Override
12599     public boolean isBackgroundVisibleBehind(IBinder token) {
12600         final long origId = Binder.clearCallingIdentity();
12601         try {
12602             synchronized (this) {
12603                 final ActivityStack stack = ActivityRecord.getStackLocked(token);
12604                 final boolean visible = stack == null ? false : stack.hasVisibleBehindActivity();
12605                 if (DEBUG_VISIBLE_BEHIND) Slog.d(TAG_VISIBLE_BEHIND,
12606                         "isBackgroundVisibleBehind: stack=" + stack + " visible=" + visible);
12607                 return visible;
12608             }
12609         } finally {
12610             Binder.restoreCallingIdentity(origId);
12611         }
12612     }
12613
12614     @Override
12615     public ActivityOptions getActivityOptions(IBinder token) {
12616         final long origId = Binder.clearCallingIdentity();
12617         try {
12618             synchronized (this) {
12619                 final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12620                 if (r != null) {
12621                     final ActivityOptions activityOptions = r.pendingOptions;
12622                     r.pendingOptions = null;
12623                     return activityOptions;
12624                 }
12625                 return null;
12626             }
12627         } finally {
12628             Binder.restoreCallingIdentity(origId);
12629         }
12630     }
12631
12632     @Override
12633     public void setImmersive(IBinder token, boolean immersive) {
12634         synchronized(this) {
12635             final ActivityRecord r = ActivityRecord.isInStackLocked(token);
12636             if (r == null) {
12637                 throw new IllegalArgumentException();
12638             }
12639             r.immersive = immersive;
12640
12641             // update associated state if we're frontmost
12642             if (r == mFocusedActivity) {
12643                 if (DEBUG_IMMERSIVE) Slog.d(TAG_IMMERSIVE, "Frontmost changed immersion: "+ r);
12644                 applyUpdateLockStateLocked(r);
12645             }
12646         }
12647     }
12648
12649     @Override
12650     public boolean isImmersive(IBinder token) {
12651         synchronized (this) {
12652             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12653             if (r == null) {
12654                 throw new IllegalArgumentException();
12655             }
12656             return r.immersive;
12657         }
12658     }
12659
12660     public void setVrThread(int tid) {
12661         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12662             throw new UnsupportedOperationException("VR mode not supported on this device!");
12663         }
12664
12665         synchronized (this) {
12666             ProcessRecord proc;
12667             synchronized (mPidsSelfLocked) {
12668                 final int pid = Binder.getCallingPid();
12669                 proc = mPidsSelfLocked.get(pid);
12670
12671                 if (proc != null && mInVrMode && tid >= 0) {
12672                     // ensure the tid belongs to the process
12673                     if (!Process.isThreadInProcess(pid, tid)) {
12674                         throw new IllegalArgumentException("VR thread does not belong to process");
12675                     }
12676
12677                     // reset existing VR thread to CFS if this thread still exists and belongs to
12678                     // the calling process
12679                     if (proc.vrThreadTid != 0
12680                             && Process.isThreadInProcess(pid, proc.vrThreadTid)) {
12681                         try {
12682                             Process.setThreadScheduler(proc.vrThreadTid, Process.SCHED_OTHER, 0);
12683                         } catch (IllegalArgumentException e) {
12684                             // Ignore this.  Only occurs in race condition where previous VR thread
12685                             // was destroyed during this method call.
12686                         }
12687                     }
12688
12689                     proc.vrThreadTid = tid;
12690
12691                     // promote to FIFO now if the tid is non-zero
12692                     try {
12693                         if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
12694                             proc.vrThreadTid > 0) {
12695                             Process.setThreadScheduler(proc.vrThreadTid,
12696                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12697                         }
12698                     } catch (IllegalArgumentException e) {
12699                         Slog.e(TAG, "Failed to set scheduling policy, thread does"
12700                                + " not exist:\n" + e);
12701                     }
12702                 }
12703             }
12704         }
12705     }
12706
12707     @Override
12708     public void setRenderThread(int tid) {
12709         synchronized (this) {
12710             ProcessRecord proc;
12711             synchronized (mPidsSelfLocked) {
12712                 int pid = Binder.getCallingPid();
12713                 proc = mPidsSelfLocked.get(pid);
12714                 if (proc != null && proc.renderThreadTid == 0 && tid > 0) {
12715                     // ensure the tid belongs to the process
12716                     if (!Process.isThreadInProcess(pid, tid)) {
12717                         throw new IllegalArgumentException(
12718                             "Render thread does not belong to process");
12719                     }
12720                     proc.renderThreadTid = tid;
12721                     if (DEBUG_OOM_ADJ) {
12722                         Slog.d("UI_FIFO", "Set RenderThread tid " + tid + " for pid " + pid);
12723                     }
12724                     // promote to FIFO now
12725                     if (proc.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
12726                         if (DEBUG_OOM_ADJ) Slog.d("UI_FIFO", "Promoting " + tid + "out of band");
12727                         if (mUseFifoUiScheduling) {
12728                             Process.setThreadScheduler(proc.renderThreadTid,
12729                                 Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
12730                         } else {
12731                             Process.setThreadPriority(proc.renderThreadTid, -10);
12732                         }
12733                     }
12734                 } else {
12735                     if (DEBUG_OOM_ADJ) {
12736                         Slog.d("UI_FIFO", "Didn't set thread from setRenderThread? " +
12737                                "PID: " + pid + ", TID: " + tid + " FIFO: " +
12738                                mUseFifoUiScheduling);
12739                     }
12740                 }
12741             }
12742         }
12743     }
12744
12745     @Override
12746     public int setVrMode(IBinder token, boolean enabled, ComponentName packageName) {
12747         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12748             throw new UnsupportedOperationException("VR mode not supported on this device!");
12749         }
12750
12751         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12752
12753         ActivityRecord r;
12754         synchronized (this) {
12755             r = ActivityRecord.isInStackLocked(token);
12756         }
12757
12758         if (r == null) {
12759             throw new IllegalArgumentException();
12760         }
12761
12762         int err;
12763         if ((err = vrService.hasVrPackage(packageName, r.userId)) !=
12764                 VrManagerInternal.NO_ERROR) {
12765             return err;
12766         }
12767
12768         synchronized(this) {
12769             r.requestedVrComponent = (enabled) ? packageName : null;
12770
12771             // Update associated state if this activity is currently focused
12772             if (r == mFocusedActivity) {
12773                 applyUpdateVrModeLocked(r);
12774             }
12775             return 0;
12776         }
12777     }
12778
12779     @Override
12780     public boolean isVrModePackageEnabled(ComponentName packageName) {
12781         if (!mContext.getPackageManager().hasSystemFeature(PackageManager.FEATURE_VR_MODE)) {
12782             throw new UnsupportedOperationException("VR mode not supported on this device!");
12783         }
12784
12785         final VrManagerInternal vrService = LocalServices.getService(VrManagerInternal.class);
12786
12787         return vrService.hasVrPackage(packageName, UserHandle.getCallingUserId()) ==
12788                 VrManagerInternal.NO_ERROR;
12789     }
12790
12791     public boolean isTopActivityImmersive() {
12792         enforceNotIsolatedCaller("startActivity");
12793         synchronized (this) {
12794             ActivityRecord r = getFocusedStack().topRunningActivityLocked();
12795             return (r != null) ? r.immersive : false;
12796         }
12797     }
12798
12799     @Override
12800     public boolean isTopOfTask(IBinder token) {
12801         synchronized (this) {
12802             ActivityRecord r = ActivityRecord.isInStackLocked(token);
12803             if (r == null) {
12804                 throw new IllegalArgumentException();
12805             }
12806             return r.task.getTopActivity() == r;
12807         }
12808     }
12809
12810     @Override
12811     public void setHasTopUi(boolean hasTopUi) throws RemoteException {
12812         if (checkCallingPermission(permission.INTERNAL_SYSTEM_WINDOW) != PERMISSION_GRANTED) {
12813             String msg = "Permission Denial: setHasTopUi() from pid="
12814                     + Binder.getCallingPid()
12815                     + ", uid=" + Binder.getCallingUid()
12816                     + " requires " + permission.INTERNAL_SYSTEM_WINDOW;
12817             Slog.w(TAG, msg);
12818             throw new SecurityException(msg);
12819         }
12820         final int pid = Binder.getCallingPid();
12821         final long origId = Binder.clearCallingIdentity();
12822         try {
12823             synchronized (this) {
12824                 boolean changed = false;
12825                 ProcessRecord pr;
12826                 synchronized (mPidsSelfLocked) {
12827                     pr = mPidsSelfLocked.get(pid);
12828                     if (pr == null) {
12829                         Slog.w(TAG, "setHasTopUi called on unknown pid: " + pid);
12830                         return;
12831                     }
12832                     if (pr.hasTopUi != hasTopUi) {
12833                         Slog.i(TAG, "Setting hasTopUi=" + hasTopUi + " for pid=" + pid);
12834                         pr.hasTopUi = hasTopUi;
12835                         changed = true;
12836                     }
12837                 }
12838                 if (changed) {
12839                     updateOomAdjLocked(pr);
12840                 }
12841             }
12842         } finally {
12843             Binder.restoreCallingIdentity(origId);
12844         }
12845     }
12846
12847     public final void enterSafeMode() {
12848         synchronized(this) {
12849             // It only makes sense to do this before the system is ready
12850             // and started launching other packages.
12851             if (!mSystemReady) {
12852                 try {
12853                     AppGlobals.getPackageManager().enterSafeMode();
12854                 } catch (RemoteException e) {
12855                 }
12856             }
12857
12858             mSafeMode = true;
12859         }
12860     }
12861
12862     public final void showSafeModeOverlay() {
12863         View v = LayoutInflater.from(mContext).inflate(
12864                 com.android.internal.R.layout.safe_mode, null);
12865         WindowManager.LayoutParams lp = new WindowManager.LayoutParams();
12866         lp.type = WindowManager.LayoutParams.TYPE_SECURE_SYSTEM_OVERLAY;
12867         lp.width = WindowManager.LayoutParams.WRAP_CONTENT;
12868         lp.height = WindowManager.LayoutParams.WRAP_CONTENT;
12869         lp.gravity = Gravity.BOTTOM | Gravity.START;
12870         lp.format = v.getBackground().getOpacity();
12871         lp.flags = WindowManager.LayoutParams.FLAG_NOT_FOCUSABLE
12872                 | WindowManager.LayoutParams.FLAG_NOT_TOUCHABLE;
12873         lp.privateFlags |= WindowManager.LayoutParams.PRIVATE_FLAG_SHOW_FOR_ALL_USERS;
12874         ((WindowManager)mContext.getSystemService(
12875                 Context.WINDOW_SERVICE)).addView(v, lp);
12876     }
12877
12878     public void noteWakeupAlarm(IIntentSender sender, int sourceUid, String sourcePkg, String tag) {
12879         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12880             return;
12881         }
12882         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12883         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12884         synchronized (stats) {
12885             if (mBatteryStatsService.isOnBattery()) {
12886                 mBatteryStatsService.enforceCallingPermission();
12887                 int MY_UID = Binder.getCallingUid();
12888                 final int uid;
12889                 if (sender == null) {
12890                     uid = sourceUid;
12891                 } else {
12892                     uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12893                 }
12894                 BatteryStatsImpl.Uid.Pkg pkg =
12895                     stats.getPackageStatsLocked(sourceUid >= 0 ? sourceUid : uid,
12896                             sourcePkg != null ? sourcePkg : rec.key.packageName);
12897                 pkg.noteWakeupAlarmLocked(tag);
12898             }
12899         }
12900     }
12901
12902     public void noteAlarmStart(IIntentSender sender, int sourceUid, String tag) {
12903         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12904             return;
12905         }
12906         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12907         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12908         synchronized (stats) {
12909             mBatteryStatsService.enforceCallingPermission();
12910             int MY_UID = Binder.getCallingUid();
12911             final int uid;
12912             if (sender == null) {
12913                 uid = sourceUid;
12914             } else {
12915                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12916             }
12917             mBatteryStatsService.noteAlarmStart(tag, sourceUid >= 0 ? sourceUid : uid);
12918         }
12919     }
12920
12921     public void noteAlarmFinish(IIntentSender sender, int sourceUid, String tag) {
12922         if (sender != null && !(sender instanceof PendingIntentRecord)) {
12923             return;
12924         }
12925         final PendingIntentRecord rec = (PendingIntentRecord)sender;
12926         final BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
12927         synchronized (stats) {
12928             mBatteryStatsService.enforceCallingPermission();
12929             int MY_UID = Binder.getCallingUid();
12930             final int uid;
12931             if (sender == null) {
12932                 uid = sourceUid;
12933             } else {
12934                 uid = rec.uid == MY_UID ? Process.SYSTEM_UID : rec.uid;
12935             }
12936             mBatteryStatsService.noteAlarmFinish(tag, sourceUid >= 0 ? sourceUid : uid);
12937         }
12938     }
12939
12940     public boolean killPids(int[] pids, String pReason, boolean secure) {
12941         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
12942             throw new SecurityException("killPids only available to the system");
12943         }
12944         String reason = (pReason == null) ? "Unknown" : pReason;
12945         // XXX Note: don't acquire main activity lock here, because the window
12946         // manager calls in with its locks held.
12947
12948         boolean killed = false;
12949         synchronized (mPidsSelfLocked) {
12950             int worstType = 0;
12951             for (int i=0; i<pids.length; i++) {
12952                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12953                 if (proc != null) {
12954                     int type = proc.setAdj;
12955                     if (type > worstType) {
12956                         worstType = type;
12957                     }
12958                 }
12959             }
12960
12961             // If the worst oom_adj is somewhere in the cached proc LRU range,
12962             // then constrain it so we will kill all cached procs.
12963             if (worstType < ProcessList.CACHED_APP_MAX_ADJ
12964                     && worstType > ProcessList.CACHED_APP_MIN_ADJ) {
12965                 worstType = ProcessList.CACHED_APP_MIN_ADJ;
12966             }
12967
12968             // If this is not a secure call, don't let it kill processes that
12969             // are important.
12970             if (!secure && worstType < ProcessList.SERVICE_ADJ) {
12971                 worstType = ProcessList.SERVICE_ADJ;
12972             }
12973
12974             Slog.w(TAG, "Killing processes " + reason + " at adjustment " + worstType);
12975             for (int i=0; i<pids.length; i++) {
12976                 ProcessRecord proc = mPidsSelfLocked.get(pids[i]);
12977                 if (proc == null) {
12978                     continue;
12979                 }
12980                 int adj = proc.setAdj;
12981                 if (adj >= worstType && !proc.killedByAm) {
12982                     proc.kill(reason, true);
12983                     killed = true;
12984                 }
12985             }
12986         }
12987         return killed;
12988     }
12989
12990     @Override
12991     public void killUid(int appId, int userId, String reason) {
12992         enforceCallingPermission(Manifest.permission.KILL_UID, "killUid");
12993         synchronized (this) {
12994             final long identity = Binder.clearCallingIdentity();
12995             try {
12996                 killPackageProcessesLocked(null, appId, userId,
12997                         ProcessList.PERSISTENT_PROC_ADJ, false, true, true, true,
12998                         reason != null ? reason : "kill uid");
12999             } finally {
13000                 Binder.restoreCallingIdentity(identity);
13001             }
13002         }
13003     }
13004
13005     @Override
13006     public boolean killProcessesBelowForeground(String reason) {
13007         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13008             throw new SecurityException("killProcessesBelowForeground() only available to system");
13009         }
13010
13011         return killProcessesBelowAdj(ProcessList.FOREGROUND_APP_ADJ, reason);
13012     }
13013
13014     private boolean killProcessesBelowAdj(int belowAdj, String reason) {
13015         if (Binder.getCallingUid() != Process.SYSTEM_UID) {
13016             throw new SecurityException("killProcessesBelowAdj() only available to system");
13017         }
13018
13019         boolean killed = false;
13020         synchronized (mPidsSelfLocked) {
13021             final int size = mPidsSelfLocked.size();
13022             for (int i = 0; i < size; i++) {
13023                 final int pid = mPidsSelfLocked.keyAt(i);
13024                 final ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13025                 if (proc == null) continue;
13026
13027                 final int adj = proc.setAdj;
13028                 if (adj > belowAdj && !proc.killedByAm) {
13029                     proc.kill(reason, true);
13030                     killed = true;
13031                 }
13032             }
13033         }
13034         return killed;
13035     }
13036
13037     @Override
13038     public void hang(final IBinder who, boolean allowRestart) {
13039         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13040                 != PackageManager.PERMISSION_GRANTED) {
13041             throw new SecurityException("Requires permission "
13042                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13043         }
13044
13045         final IBinder.DeathRecipient death = new DeathRecipient() {
13046             @Override
13047             public void binderDied() {
13048                 synchronized (this) {
13049                     notifyAll();
13050                 }
13051             }
13052         };
13053
13054         try {
13055             who.linkToDeath(death, 0);
13056         } catch (RemoteException e) {
13057             Slog.w(TAG, "hang: given caller IBinder is already dead.");
13058             return;
13059         }
13060
13061         synchronized (this) {
13062             Watchdog.getInstance().setAllowRestart(allowRestart);
13063             Slog.i(TAG, "Hanging system process at request of pid " + Binder.getCallingPid());
13064             synchronized (death) {
13065                 while (who.isBinderAlive()) {
13066                     try {
13067                         death.wait();
13068                     } catch (InterruptedException e) {
13069                     }
13070                 }
13071             }
13072             Watchdog.getInstance().setAllowRestart(true);
13073         }
13074     }
13075
13076     @Override
13077     public void restart() {
13078         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13079                 != PackageManager.PERMISSION_GRANTED) {
13080             throw new SecurityException("Requires permission "
13081                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13082         }
13083
13084         Log.i(TAG, "Sending shutdown broadcast...");
13085
13086         BroadcastReceiver br = new BroadcastReceiver() {
13087             @Override public void onReceive(Context context, Intent intent) {
13088                 // Now the broadcast is done, finish up the low-level shutdown.
13089                 Log.i(TAG, "Shutting down activity manager...");
13090                 shutdown(10000);
13091                 Log.i(TAG, "Shutdown complete, restarting!");
13092                 Process.killProcess(Process.myPid());
13093                 System.exit(10);
13094             }
13095         };
13096
13097         // First send the high-level shut down broadcast.
13098         Intent intent = new Intent(Intent.ACTION_SHUTDOWN);
13099         intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
13100         intent.putExtra(Intent.EXTRA_SHUTDOWN_USERSPACE_ONLY, true);
13101         /* For now we are not doing a clean shutdown, because things seem to get unhappy.
13102         mContext.sendOrderedBroadcastAsUser(intent,
13103                 UserHandle.ALL, null, br, mHandler, 0, null, null);
13104         */
13105         br.onReceive(mContext, intent);
13106     }
13107
13108     private long getLowRamTimeSinceIdle(long now) {
13109         return mLowRamTimeSinceLastIdle + (mLowRamStartTime > 0 ? (now-mLowRamStartTime) : 0);
13110     }
13111
13112     @Override
13113     public void performIdleMaintenance() {
13114         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13115                 != PackageManager.PERMISSION_GRANTED) {
13116             throw new SecurityException("Requires permission "
13117                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13118         }
13119
13120         synchronized (this) {
13121             final long now = SystemClock.uptimeMillis();
13122             final long timeSinceLastIdle = now - mLastIdleTime;
13123             final long lowRamSinceLastIdle = getLowRamTimeSinceIdle(now);
13124             mLastIdleTime = now;
13125             mLowRamTimeSinceLastIdle = 0;
13126             if (mLowRamStartTime != 0) {
13127                 mLowRamStartTime = now;
13128             }
13129
13130             StringBuilder sb = new StringBuilder(128);
13131             sb.append("Idle maintenance over ");
13132             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13133             sb.append(" low RAM for ");
13134             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13135             Slog.i(TAG, sb.toString());
13136
13137             // If at least 1/3 of our time since the last idle period has been spent
13138             // with RAM low, then we want to kill processes.
13139             boolean doKilling = lowRamSinceLastIdle > (timeSinceLastIdle/3);
13140
13141             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
13142                 ProcessRecord proc = mLruProcesses.get(i);
13143                 if (proc.notCachedSinceIdle) {
13144                     if (proc.setProcState != ActivityManager.PROCESS_STATE_TOP_SLEEPING
13145                             && proc.setProcState >= ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE
13146                             && proc.setProcState <= ActivityManager.PROCESS_STATE_SERVICE) {
13147                         if (doKilling && proc.initialIdlePss != 0
13148                                 && proc.lastPss > ((proc.initialIdlePss*3)/2)) {
13149                             sb = new StringBuilder(128);
13150                             sb.append("Kill");
13151                             sb.append(proc.processName);
13152                             sb.append(" in idle maint: pss=");
13153                             sb.append(proc.lastPss);
13154                             sb.append(", swapPss=");
13155                             sb.append(proc.lastSwapPss);
13156                             sb.append(", initialPss=");
13157                             sb.append(proc.initialIdlePss);
13158                             sb.append(", period=");
13159                             TimeUtils.formatDuration(timeSinceLastIdle, sb);
13160                             sb.append(", lowRamPeriod=");
13161                             TimeUtils.formatDuration(lowRamSinceLastIdle, sb);
13162                             Slog.wtfQuiet(TAG, sb.toString());
13163                             proc.kill("idle maint (pss " + proc.lastPss
13164                                     + " from " + proc.initialIdlePss + ")", true);
13165                         }
13166                     }
13167                 } else if (proc.setProcState < ActivityManager.PROCESS_STATE_HOME
13168                         && proc.setProcState > ActivityManager.PROCESS_STATE_NONEXISTENT) {
13169                     proc.notCachedSinceIdle = true;
13170                     proc.initialIdlePss = 0;
13171                     proc.nextPssTime = ProcessList.computeNextPssTime(proc.setProcState, true,
13172                             mTestPssMode, isSleepingLocked(), now);
13173                 }
13174             }
13175
13176             mHandler.removeMessages(REQUEST_ALL_PSS_MSG);
13177             mHandler.sendEmptyMessageDelayed(REQUEST_ALL_PSS_MSG, 2*60*1000);
13178         }
13179     }
13180
13181     @Override
13182     public void sendIdleJobTrigger() {
13183         if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
13184                 != PackageManager.PERMISSION_GRANTED) {
13185             throw new SecurityException("Requires permission "
13186                     + android.Manifest.permission.SET_ACTIVITY_WATCHER);
13187         }
13188
13189         final long ident = Binder.clearCallingIdentity();
13190         try {
13191             Intent intent = new Intent(ACTION_TRIGGER_IDLE)
13192                     .setPackage("android")
13193                     .addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13194             broadcastIntent(null, intent, null, null, 0, null, null, null,
13195                     android.app.AppOpsManager.OP_NONE, null, true, false, UserHandle.USER_ALL);
13196         } finally {
13197             Binder.restoreCallingIdentity(ident);
13198         }
13199     }
13200
13201     private void retrieveSettings() {
13202         final ContentResolver resolver = mContext.getContentResolver();
13203         final boolean freeformWindowManagement =
13204                 mContext.getPackageManager().hasSystemFeature(FEATURE_FREEFORM_WINDOW_MANAGEMENT)
13205                         || Settings.Global.getInt(
13206                                 resolver, DEVELOPMENT_ENABLE_FREEFORM_WINDOWS_SUPPORT, 0) != 0;
13207         final boolean supportsPictureInPicture =
13208                 mContext.getPackageManager().hasSystemFeature(FEATURE_PICTURE_IN_PICTURE);
13209
13210         final boolean supportsMultiWindow = ActivityManager.supportsMultiWindow();
13211         final String debugApp = Settings.Global.getString(resolver, DEBUG_APP);
13212         final boolean waitForDebugger = Settings.Global.getInt(resolver, WAIT_FOR_DEBUGGER, 0) != 0;
13213         final boolean alwaysFinishActivities =
13214                 Settings.Global.getInt(resolver, ALWAYS_FINISH_ACTIVITIES, 0) != 0;
13215         final boolean lenientBackgroundCheck =
13216                 Settings.Global.getInt(resolver, LENIENT_BACKGROUND_CHECK, 0) != 0;
13217         final boolean forceRtl = Settings.Global.getInt(resolver, DEVELOPMENT_FORCE_RTL, 0) != 0;
13218         final boolean forceResizable = Settings.Global.getInt(
13219                 resolver, DEVELOPMENT_FORCE_RESIZABLE_ACTIVITIES, 0) != 0;
13220         final boolean supportsLeanbackOnly =
13221                 mContext.getPackageManager().hasSystemFeature(FEATURE_LEANBACK_ONLY);
13222
13223         // Transfer any global setting for forcing RTL layout, into a System Property
13224         SystemProperties.set(DEVELOPMENT_FORCE_RTL, forceRtl ? "1":"0");
13225
13226         final Configuration configuration = new Configuration();
13227         Settings.System.getConfiguration(resolver, configuration);
13228         if (forceRtl) {
13229             // This will take care of setting the correct layout direction flags
13230             configuration.setLayoutDirection(configuration.locale);
13231         }
13232
13233         synchronized (this) {
13234             mDebugApp = mOrigDebugApp = debugApp;
13235             mWaitForDebugger = mOrigWaitForDebugger = waitForDebugger;
13236             mAlwaysFinishActivities = alwaysFinishActivities;
13237             mLenientBackgroundCheck = lenientBackgroundCheck;
13238             mSupportsLeanbackOnly = supportsLeanbackOnly;
13239             mForceResizableActivities = forceResizable;
13240             mWindowManager.setForceResizableTasks(mForceResizableActivities);
13241             if (supportsMultiWindow || forceResizable) {
13242                 mSupportsMultiWindow = true;
13243                 mSupportsFreeformWindowManagement = freeformWindowManagement || forceResizable;
13244                 mSupportsPictureInPicture = supportsPictureInPicture || forceResizable;
13245             } else {
13246                 mSupportsMultiWindow = false;
13247                 mSupportsFreeformWindowManagement = false;
13248                 mSupportsPictureInPicture = false;
13249             }
13250             // This happens before any activities are started, so we can
13251             // change mConfiguration in-place.
13252             updateConfigurationLocked(configuration, null, true);
13253             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION,
13254                     "Initial config: " + mConfiguration);
13255
13256             // Load resources only after the current configuration has been set.
13257             final Resources res = mContext.getResources();
13258             mHasRecents = res.getBoolean(com.android.internal.R.bool.config_hasRecents);
13259             mThumbnailWidth = res.getDimensionPixelSize(
13260                     com.android.internal.R.dimen.thumbnail_width);
13261             mThumbnailHeight = res.getDimensionPixelSize(
13262                     com.android.internal.R.dimen.thumbnail_height);
13263             mDefaultPinnedStackBounds = Rect.unflattenFromString(res.getString(
13264                     com.android.internal.R.string.config_defaultPictureInPictureBounds));
13265             mAppErrors.loadAppsNotReportingCrashesFromConfigLocked(res.getString(
13266                     com.android.internal.R.string.config_appsNotReportingCrashes));
13267             if ((mConfiguration.uiMode & UI_MODE_TYPE_TELEVISION) == UI_MODE_TYPE_TELEVISION) {
13268                 mFullscreenThumbnailScale = (float) res
13269                     .getInteger(com.android.internal.R.integer.thumbnail_width_tv) /
13270                     (float) mConfiguration.screenWidthDp;
13271             } else {
13272                 mFullscreenThumbnailScale = res.getFraction(
13273                     com.android.internal.R.fraction.thumbnail_fullscreen_scale, 1, 1);
13274             }
13275         }
13276     }
13277
13278     public boolean testIsSystemReady() {
13279         // no need to synchronize(this) just to read & return the value
13280         return mSystemReady;
13281     }
13282
13283     public void systemReady(final Runnable goingCallback) {
13284         synchronized(this) {
13285             if (mSystemReady) {
13286                 // If we're done calling all the receivers, run the next "boot phase" passed in
13287                 // by the SystemServer
13288                 if (goingCallback != null) {
13289                     goingCallback.run();
13290                 }
13291                 return;
13292             }
13293
13294             mLocalDeviceIdleController
13295                     = LocalServices.getService(DeviceIdleController.LocalService.class);
13296
13297             // Make sure we have the current profile info, since it is needed for security checks.
13298             mUserController.onSystemReady();
13299             mRecentTasks.onSystemReadyLocked();
13300             mAppOpsService.systemReady();
13301             mSystemReady = true;
13302         }
13303
13304         ArrayList<ProcessRecord> procsToKill = null;
13305         synchronized(mPidsSelfLocked) {
13306             for (int i=mPidsSelfLocked.size()-1; i>=0; i--) {
13307                 ProcessRecord proc = mPidsSelfLocked.valueAt(i);
13308                 if (!isAllowedWhileBooting(proc.info)){
13309                     if (procsToKill == null) {
13310                         procsToKill = new ArrayList<ProcessRecord>();
13311                     }
13312                     procsToKill.add(proc);
13313                 }
13314             }
13315         }
13316
13317         synchronized(this) {
13318             if (procsToKill != null) {
13319                 for (int i=procsToKill.size()-1; i>=0; i--) {
13320                     ProcessRecord proc = procsToKill.get(i);
13321                     Slog.i(TAG, "Removing system update proc: " + proc);
13322                     removeProcessLocked(proc, true, false, "system update done");
13323                 }
13324             }
13325
13326             // Now that we have cleaned up any update processes, we
13327             // are ready to start launching real processes and know that
13328             // we won't trample on them any more.
13329             mProcessesReady = true;
13330         }
13331
13332         Slog.i(TAG, "System now ready");
13333         EventLog.writeEvent(EventLogTags.BOOT_PROGRESS_AMS_READY,
13334             SystemClock.uptimeMillis());
13335
13336         synchronized(this) {
13337             // Make sure we have no pre-ready processes sitting around.
13338
13339             if (mFactoryTest == FactoryTest.FACTORY_TEST_LOW_LEVEL) {
13340                 ResolveInfo ri = mContext.getPackageManager()
13341                         .resolveActivity(new Intent(Intent.ACTION_FACTORY_TEST),
13342                                 STOCK_PM_FLAGS);
13343                 CharSequence errorMsg = null;
13344                 if (ri != null) {
13345                     ActivityInfo ai = ri.activityInfo;
13346                     ApplicationInfo app = ai.applicationInfo;
13347                     if ((app.flags&ApplicationInfo.FLAG_SYSTEM) != 0) {
13348                         mTopAction = Intent.ACTION_FACTORY_TEST;
13349                         mTopData = null;
13350                         mTopComponent = new ComponentName(app.packageName,
13351                                 ai.name);
13352                     } else {
13353                         errorMsg = mContext.getResources().getText(
13354                                 com.android.internal.R.string.factorytest_not_system);
13355                     }
13356                 } else {
13357                     errorMsg = mContext.getResources().getText(
13358                             com.android.internal.R.string.factorytest_no_action);
13359                 }
13360                 if (errorMsg != null) {
13361                     mTopAction = null;
13362                     mTopData = null;
13363                     mTopComponent = null;
13364                     Message msg = Message.obtain();
13365                     msg.what = SHOW_FACTORY_ERROR_UI_MSG;
13366                     msg.getData().putCharSequence("msg", errorMsg);
13367                     mUiHandler.sendMessage(msg);
13368                 }
13369             }
13370         }
13371
13372         retrieveSettings();
13373         final int currentUserId;
13374         synchronized (this) {
13375             currentUserId = mUserController.getCurrentUserIdLocked();
13376             readGrantedUriPermissionsLocked();
13377         }
13378
13379         if (goingCallback != null) goingCallback.run();
13380
13381         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_RUNNING_START,
13382                 Integer.toString(currentUserId), currentUserId);
13383         mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_USER_FOREGROUND_START,
13384                 Integer.toString(currentUserId), currentUserId);
13385         mSystemServiceManager.startUser(currentUserId);
13386
13387         synchronized (this) {
13388             // Only start up encryption-aware persistent apps; once user is
13389             // unlocked we'll come back around and start unaware apps
13390             startPersistentApps(PackageManager.MATCH_DIRECT_BOOT_AWARE);
13391
13392             // Start up initial activity.
13393             mBooting = true;
13394             // Enable home activity for system user, so that the system can always boot
13395             if (UserManager.isSplitSystemUser()) {
13396                 ComponentName cName = new ComponentName(mContext, SystemUserHomeActivity.class);
13397                 try {
13398                     AppGlobals.getPackageManager().setComponentEnabledSetting(cName,
13399                             PackageManager.COMPONENT_ENABLED_STATE_ENABLED, 0,
13400                             UserHandle.USER_SYSTEM);
13401                 } catch (RemoteException e) {
13402                     throw e.rethrowAsRuntimeException();
13403                 }
13404             }
13405             startHomeActivityLocked(currentUserId, "systemReady");
13406
13407             try {
13408                 if (AppGlobals.getPackageManager().hasSystemUidErrors()) {
13409                     Slog.e(TAG, "UIDs on the system are inconsistent, you need to wipe your"
13410                             + " data partition or your device will be unstable.");
13411                     mUiHandler.obtainMessage(SHOW_UID_ERROR_UI_MSG).sendToTarget();
13412                 }
13413             } catch (RemoteException e) {
13414             }
13415
13416             if (!Build.isBuildConsistent()) {
13417                 Slog.e(TAG, "Build fingerprint is not consistent, warning user");
13418                 mUiHandler.obtainMessage(SHOW_FINGERPRINT_ERROR_UI_MSG).sendToTarget();
13419             }
13420
13421             long ident = Binder.clearCallingIdentity();
13422             try {
13423                 Intent intent = new Intent(Intent.ACTION_USER_STARTED);
13424                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
13425                         | Intent.FLAG_RECEIVER_FOREGROUND);
13426                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13427                 broadcastIntentLocked(null, null, intent,
13428                         null, null, 0, null, null, null, AppOpsManager.OP_NONE,
13429                         null, false, false, MY_PID, Process.SYSTEM_UID,
13430                         currentUserId);
13431                 intent = new Intent(Intent.ACTION_USER_STARTING);
13432                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
13433                 intent.putExtra(Intent.EXTRA_USER_HANDLE, currentUserId);
13434                 broadcastIntentLocked(null, null, intent,
13435                         null, new IIntentReceiver.Stub() {
13436                             @Override
13437                             public void performReceive(Intent intent, int resultCode, String data,
13438                                     Bundle extras, boolean ordered, boolean sticky, int sendingUser)
13439                                     throws RemoteException {
13440                             }
13441                         }, 0, null, null,
13442                         new String[] {INTERACT_ACROSS_USERS}, AppOpsManager.OP_NONE,
13443                         null, true, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
13444             } catch (Throwable t) {
13445                 Slog.wtf(TAG, "Failed sending first user broadcasts", t);
13446             } finally {
13447                 Binder.restoreCallingIdentity(ident);
13448             }
13449             mStackSupervisor.resumeFocusedStackTopActivityLocked();
13450             mUserController.sendUserSwitchBroadcastsLocked(-1, currentUserId);
13451         }
13452     }
13453
13454     void killAppAtUsersRequest(ProcessRecord app, Dialog fromDialog) {
13455         synchronized (this) {
13456             mAppErrors.killAppAtUserRequestLocked(app, fromDialog);
13457         }
13458     }
13459
13460     void skipCurrentReceiverLocked(ProcessRecord app) {
13461         for (BroadcastQueue queue : mBroadcastQueues) {
13462             queue.skipCurrentReceiverLocked(app);
13463         }
13464     }
13465
13466     /**
13467      * Used by {@link com.android.internal.os.RuntimeInit} to report when an application crashes.
13468      * The application process will exit immediately after this call returns.
13469      * @param app object of the crashing app, null for the system server
13470      * @param crashInfo describing the exception
13471      */
13472     public void handleApplicationCrash(IBinder app, ApplicationErrorReport.CrashInfo crashInfo) {
13473         ProcessRecord r = findAppProcess(app, "Crash");
13474         final String processName = app == null ? "system_server"
13475                 : (r == null ? "unknown" : r.processName);
13476
13477         handleApplicationCrashInner("crash", r, processName, crashInfo);
13478     }
13479
13480     /* Native crash reporting uses this inner version because it needs to be somewhat
13481      * decoupled from the AM-managed cleanup lifecycle
13482      */
13483     void handleApplicationCrashInner(String eventType, ProcessRecord r, String processName,
13484             ApplicationErrorReport.CrashInfo crashInfo) {
13485         EventLog.writeEvent(EventLogTags.AM_CRASH, Binder.getCallingPid(),
13486                 UserHandle.getUserId(Binder.getCallingUid()), processName,
13487                 r == null ? -1 : r.info.flags,
13488                 crashInfo.exceptionClassName,
13489                 crashInfo.exceptionMessage,
13490                 crashInfo.throwFileName,
13491                 crashInfo.throwLineNumber);
13492
13493         addErrorToDropBox(eventType, r, processName, null, null, null, null, null, crashInfo);
13494
13495         mAppErrors.crashApplication(r, crashInfo);
13496     }
13497
13498     public void handleApplicationStrictModeViolation(
13499             IBinder app,
13500             int violationMask,
13501             StrictMode.ViolationInfo info) {
13502         ProcessRecord r = findAppProcess(app, "StrictMode");
13503         if (r == null) {
13504             return;
13505         }
13506
13507         if ((violationMask & StrictMode.PENALTY_DROPBOX) != 0) {
13508             Integer stackFingerprint = info.hashCode();
13509             boolean logIt = true;
13510             synchronized (mAlreadyLoggedViolatedStacks) {
13511                 if (mAlreadyLoggedViolatedStacks.contains(stackFingerprint)) {
13512                     logIt = false;
13513                     // TODO: sub-sample into EventLog for these, with
13514                     // the info.durationMillis?  Then we'd get
13515                     // the relative pain numbers, without logging all
13516                     // the stack traces repeatedly.  We'd want to do
13517                     // likewise in the client code, which also does
13518                     // dup suppression, before the Binder call.
13519                 } else {
13520                     if (mAlreadyLoggedViolatedStacks.size() >= MAX_DUP_SUPPRESSED_STACKS) {
13521                         mAlreadyLoggedViolatedStacks.clear();
13522                     }
13523                     mAlreadyLoggedViolatedStacks.add(stackFingerprint);
13524                 }
13525             }
13526             if (logIt) {
13527                 logStrictModeViolationToDropBox(r, info);
13528             }
13529         }
13530
13531         if ((violationMask & StrictMode.PENALTY_DIALOG) != 0) {
13532             AppErrorResult result = new AppErrorResult();
13533             synchronized (this) {
13534                 final long origId = Binder.clearCallingIdentity();
13535
13536                 Message msg = Message.obtain();
13537                 msg.what = SHOW_STRICT_MODE_VIOLATION_UI_MSG;
13538                 HashMap<String, Object> data = new HashMap<String, Object>();
13539                 data.put("result", result);
13540                 data.put("app", r);
13541                 data.put("violationMask", violationMask);
13542                 data.put("info", info);
13543                 msg.obj = data;
13544                 mUiHandler.sendMessage(msg);
13545
13546                 Binder.restoreCallingIdentity(origId);
13547             }
13548             int res = result.get();
13549             Slog.w(TAG, "handleApplicationStrictModeViolation; res=" + res);
13550         }
13551     }
13552
13553     // Depending on the policy in effect, there could be a bunch of
13554     // these in quick succession so we try to batch these together to
13555     // minimize disk writes, number of dropbox entries, and maximize
13556     // compression, by having more fewer, larger records.
13557     private void logStrictModeViolationToDropBox(
13558             ProcessRecord process,
13559             StrictMode.ViolationInfo info) {
13560         if (info == null) {
13561             return;
13562         }
13563         final boolean isSystemApp = process == null ||
13564                 (process.info.flags & (ApplicationInfo.FLAG_SYSTEM |
13565                                        ApplicationInfo.FLAG_UPDATED_SYSTEM_APP)) != 0;
13566         final String processName = process == null ? "unknown" : process.processName;
13567         final String dropboxTag = isSystemApp ? "system_app_strictmode" : "data_app_strictmode";
13568         final DropBoxManager dbox = (DropBoxManager)
13569                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13570
13571         // Exit early if the dropbox isn't configured to accept this report type.
13572         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13573
13574         boolean bufferWasEmpty;
13575         boolean needsFlush;
13576         final StringBuilder sb = isSystemApp ? mStrictModeBuffer : new StringBuilder(1024);
13577         synchronized (sb) {
13578             bufferWasEmpty = sb.length() == 0;
13579             appendDropBoxProcessHeaders(process, processName, sb);
13580             sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13581             sb.append("System-App: ").append(isSystemApp).append("\n");
13582             sb.append("Uptime-Millis: ").append(info.violationUptimeMillis).append("\n");
13583             if (info.violationNumThisLoop != 0) {
13584                 sb.append("Loop-Violation-Number: ").append(info.violationNumThisLoop).append("\n");
13585             }
13586             if (info.numAnimationsRunning != 0) {
13587                 sb.append("Animations-Running: ").append(info.numAnimationsRunning).append("\n");
13588             }
13589             if (info.broadcastIntentAction != null) {
13590                 sb.append("Broadcast-Intent-Action: ").append(info.broadcastIntentAction).append("\n");
13591             }
13592             if (info.durationMillis != -1) {
13593                 sb.append("Duration-Millis: ").append(info.durationMillis).append("\n");
13594             }
13595             if (info.numInstances != -1) {
13596                 sb.append("Instance-Count: ").append(info.numInstances).append("\n");
13597             }
13598             if (info.tags != null) {
13599                 for (String tag : info.tags) {
13600                     sb.append("Span-Tag: ").append(tag).append("\n");
13601                 }
13602             }
13603             sb.append("\n");
13604             if (info.crashInfo != null && info.crashInfo.stackTrace != null) {
13605                 sb.append(info.crashInfo.stackTrace);
13606                 sb.append("\n");
13607             }
13608             if (info.message != null) {
13609                 sb.append(info.message);
13610                 sb.append("\n");
13611             }
13612
13613             // Only buffer up to ~64k.  Various logging bits truncate
13614             // things at 128k.
13615             needsFlush = (sb.length() > 64 * 1024);
13616         }
13617
13618         // Flush immediately if the buffer's grown too large, or this
13619         // is a non-system app.  Non-system apps are isolated with a
13620         // different tag & policy and not batched.
13621         //
13622         // Batching is useful during internal testing with
13623         // StrictMode settings turned up high.  Without batching,
13624         // thousands of separate files could be created on boot.
13625         if (!isSystemApp || needsFlush) {
13626             new Thread("Error dump: " + dropboxTag) {
13627                 @Override
13628                 public void run() {
13629                     String report;
13630                     synchronized (sb) {
13631                         report = sb.toString();
13632                         sb.delete(0, sb.length());
13633                         sb.trimToSize();
13634                     }
13635                     if (report.length() != 0) {
13636                         dbox.addText(dropboxTag, report);
13637                     }
13638                 }
13639             }.start();
13640             return;
13641         }
13642
13643         // System app batching:
13644         if (!bufferWasEmpty) {
13645             // An existing dropbox-writing thread is outstanding, so
13646             // we don't need to start it up.  The existing thread will
13647             // catch the buffer appends we just did.
13648             return;
13649         }
13650
13651         // Worker thread to both batch writes and to avoid blocking the caller on I/O.
13652         // (After this point, we shouldn't access AMS internal data structures.)
13653         new Thread("Error dump: " + dropboxTag) {
13654             @Override
13655             public void run() {
13656                 // 5 second sleep to let stacks arrive and be batched together
13657                 try {
13658                     Thread.sleep(5000);  // 5 seconds
13659                 } catch (InterruptedException e) {}
13660
13661                 String errorReport;
13662                 synchronized (mStrictModeBuffer) {
13663                     errorReport = mStrictModeBuffer.toString();
13664                     if (errorReport.length() == 0) {
13665                         return;
13666                     }
13667                     mStrictModeBuffer.delete(0, mStrictModeBuffer.length());
13668                     mStrictModeBuffer.trimToSize();
13669                 }
13670                 dbox.addText(dropboxTag, errorReport);
13671             }
13672         }.start();
13673     }
13674
13675     /**
13676      * Used by {@link Log} via {@link com.android.internal.os.RuntimeInit} to report serious errors.
13677      * @param app object of the crashing app, null for the system server
13678      * @param tag reported by the caller
13679      * @param system whether this wtf is coming from the system
13680      * @param crashInfo describing the context of the error
13681      * @return true if the process should exit immediately (WTF is fatal)
13682      */
13683     public boolean handleApplicationWtf(final IBinder app, final String tag, boolean system,
13684             final ApplicationErrorReport.CrashInfo crashInfo) {
13685         final int callingUid = Binder.getCallingUid();
13686         final int callingPid = Binder.getCallingPid();
13687
13688         if (system) {
13689             // If this is coming from the system, we could very well have low-level
13690             // system locks held, so we want to do this all asynchronously.  And we
13691             // never want this to become fatal, so there is that too.
13692             mHandler.post(new Runnable() {
13693                 @Override public void run() {
13694                     handleApplicationWtfInner(callingUid, callingPid, app, tag, crashInfo);
13695                 }
13696             });
13697             return false;
13698         }
13699
13700         final ProcessRecord r = handleApplicationWtfInner(callingUid, callingPid, app, tag,
13701                 crashInfo);
13702
13703         if (r != null && r.pid != Process.myPid() &&
13704                 Settings.Global.getInt(mContext.getContentResolver(),
13705                         Settings.Global.WTF_IS_FATAL, 0) != 0) {
13706             mAppErrors.crashApplication(r, crashInfo);
13707             return true;
13708         } else {
13709             return false;
13710         }
13711     }
13712
13713     ProcessRecord handleApplicationWtfInner(int callingUid, int callingPid, IBinder app, String tag,
13714             final ApplicationErrorReport.CrashInfo crashInfo) {
13715         final ProcessRecord r = findAppProcess(app, "WTF");
13716         final String processName = app == null ? "system_server"
13717                 : (r == null ? "unknown" : r.processName);
13718
13719         EventLog.writeEvent(EventLogTags.AM_WTF, UserHandle.getUserId(callingUid), callingPid,
13720                 processName, r == null ? -1 : r.info.flags, tag, crashInfo.exceptionMessage);
13721
13722         addErrorToDropBox("wtf", r, processName, null, null, tag, null, null, crashInfo);
13723
13724         return r;
13725     }
13726
13727     /**
13728      * @param app object of some object (as stored in {@link com.android.internal.os.RuntimeInit})
13729      * @return the corresponding {@link ProcessRecord} object, or null if none could be found
13730      */
13731     private ProcessRecord findAppProcess(IBinder app, String reason) {
13732         if (app == null) {
13733             return null;
13734         }
13735
13736         synchronized (this) {
13737             final int NP = mProcessNames.getMap().size();
13738             for (int ip=0; ip<NP; ip++) {
13739                 SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
13740                 final int NA = apps.size();
13741                 for (int ia=0; ia<NA; ia++) {
13742                     ProcessRecord p = apps.valueAt(ia);
13743                     if (p.thread != null && p.thread.asBinder() == app) {
13744                         return p;
13745                     }
13746                 }
13747             }
13748
13749             Slog.w(TAG, "Can't find mystery application for " + reason
13750                     + " from pid=" + Binder.getCallingPid()
13751                     + " uid=" + Binder.getCallingUid() + ": " + app);
13752             return null;
13753         }
13754     }
13755
13756     /**
13757      * Utility function for addErrorToDropBox and handleStrictModeViolation's logging
13758      * to append various headers to the dropbox log text.
13759      */
13760     private void appendDropBoxProcessHeaders(ProcessRecord process, String processName,
13761             StringBuilder sb) {
13762         // Watchdog thread ends up invoking this function (with
13763         // a null ProcessRecord) to add the stack file to dropbox.
13764         // Do not acquire a lock on this (am) in such cases, as it
13765         // could cause a potential deadlock, if and when watchdog
13766         // is invoked due to unavailability of lock on am and it
13767         // would prevent watchdog from killing system_server.
13768         if (process == null) {
13769             sb.append("Process: ").append(processName).append("\n");
13770             return;
13771         }
13772         // Note: ProcessRecord 'process' is guarded by the service
13773         // instance.  (notably process.pkgList, which could otherwise change
13774         // concurrently during execution of this method)
13775         synchronized (this) {
13776             sb.append("Process: ").append(processName).append("\n");
13777             int flags = process.info.flags;
13778             IPackageManager pm = AppGlobals.getPackageManager();
13779             sb.append("Flags: 0x").append(Integer.toHexString(flags)).append("\n");
13780             for (int ip=0; ip<process.pkgList.size(); ip++) {
13781                 String pkg = process.pkgList.keyAt(ip);
13782                 sb.append("Package: ").append(pkg);
13783                 try {
13784                     PackageInfo pi = pm.getPackageInfo(pkg, 0, UserHandle.getCallingUserId());
13785                     if (pi != null) {
13786                         sb.append(" v").append(pi.versionCode);
13787                         if (pi.versionName != null) {
13788                             sb.append(" (").append(pi.versionName).append(")");
13789                         }
13790                     }
13791                 } catch (RemoteException e) {
13792                     Slog.e(TAG, "Error getting package info: " + pkg, e);
13793                 }
13794                 sb.append("\n");
13795             }
13796         }
13797     }
13798
13799     private static String processClass(ProcessRecord process) {
13800         if (process == null || process.pid == MY_PID) {
13801             return "system_server";
13802         } else if ((process.info.flags & ApplicationInfo.FLAG_SYSTEM) != 0) {
13803             return "system_app";
13804         } else {
13805             return "data_app";
13806         }
13807     }
13808
13809     private volatile long mWtfClusterStart;
13810     private volatile int mWtfClusterCount;
13811
13812     /**
13813      * Write a description of an error (crash, WTF, ANR) to the drop box.
13814      * @param eventType to include in the drop box tag ("crash", "wtf", etc.)
13815      * @param process which caused the error, null means the system server
13816      * @param activity which triggered the error, null if unknown
13817      * @param parent activity related to the error, null if unknown
13818      * @param subject line related to the error, null if absent
13819      * @param report in long form describing the error, null if absent
13820      * @param dataFile text file to include in the report, null if none
13821      * @param crashInfo giving an application stack trace, null if absent
13822      */
13823     public void addErrorToDropBox(String eventType,
13824             ProcessRecord process, String processName, ActivityRecord activity,
13825             ActivityRecord parent, String subject,
13826             final String report, final File dataFile,
13827             final ApplicationErrorReport.CrashInfo crashInfo) {
13828         // NOTE -- this must never acquire the ActivityManagerService lock,
13829         // otherwise the watchdog may be prevented from resetting the system.
13830
13831         final String dropboxTag = processClass(process) + "_" + eventType;
13832         final DropBoxManager dbox = (DropBoxManager)
13833                 mContext.getSystemService(Context.DROPBOX_SERVICE);
13834
13835         // Exit early if the dropbox isn't configured to accept this report type.
13836         if (dbox == null || !dbox.isTagEnabled(dropboxTag)) return;
13837
13838         // Rate-limit how often we're willing to do the heavy lifting below to
13839         // collect and record logs; currently 5 logs per 10 second period.
13840         final long now = SystemClock.elapsedRealtime();
13841         if (now - mWtfClusterStart > 10 * DateUtils.SECOND_IN_MILLIS) {
13842             mWtfClusterStart = now;
13843             mWtfClusterCount = 1;
13844         } else {
13845             if (mWtfClusterCount++ >= 5) return;
13846         }
13847
13848         final StringBuilder sb = new StringBuilder(1024);
13849         appendDropBoxProcessHeaders(process, processName, sb);
13850         if (process != null) {
13851             sb.append("Foreground: ")
13852                     .append(process.isInterestingToUserLocked() ? "Yes" : "No")
13853                     .append("\n");
13854         }
13855         if (activity != null) {
13856             sb.append("Activity: ").append(activity.shortComponentName).append("\n");
13857         }
13858         if (parent != null && parent.app != null && parent.app.pid != process.pid) {
13859             sb.append("Parent-Process: ").append(parent.app.processName).append("\n");
13860         }
13861         if (parent != null && parent != activity) {
13862             sb.append("Parent-Activity: ").append(parent.shortComponentName).append("\n");
13863         }
13864         if (subject != null) {
13865             sb.append("Subject: ").append(subject).append("\n");
13866         }
13867         sb.append("Build: ").append(Build.FINGERPRINT).append("\n");
13868         if (Debug.isDebuggerConnected()) {
13869             sb.append("Debugger: Connected\n");
13870         }
13871         sb.append("\n");
13872
13873         // Do the rest in a worker thread to avoid blocking the caller on I/O
13874         // (After this point, we shouldn't access AMS internal data structures.)
13875         Thread worker = new Thread("Error dump: " + dropboxTag) {
13876             @Override
13877             public void run() {
13878                 if (report != null) {
13879                     sb.append(report);
13880                 }
13881
13882                 String setting = Settings.Global.ERROR_LOGCAT_PREFIX + dropboxTag;
13883                 int lines = Settings.Global.getInt(mContext.getContentResolver(), setting, 0);
13884                 int maxDataFileSize = DROPBOX_MAX_SIZE - sb.length()
13885                         - lines * RESERVED_BYTES_PER_LOGCAT_LINE;
13886
13887                 if (dataFile != null && maxDataFileSize > 0) {
13888                     try {
13889                         sb.append(FileUtils.readTextFile(dataFile, maxDataFileSize,
13890                                     "\n\n[[TRUNCATED]]"));
13891                     } catch (IOException e) {
13892                         Slog.e(TAG, "Error reading " + dataFile, e);
13893                     }
13894                 }
13895                 if (crashInfo != null && crashInfo.stackTrace != null) {
13896                     sb.append(crashInfo.stackTrace);
13897                 }
13898
13899                 if (lines > 0) {
13900                     sb.append("\n");
13901
13902                     // Merge several logcat streams, and take the last N lines
13903                     InputStreamReader input = null;
13904                     try {
13905                         java.lang.Process logcat = new ProcessBuilder(
13906                                 "/system/bin/timeout", "-k", "15s", "10s",
13907                                 "/system/bin/logcat", "-v", "threadtime", "-b", "events", "-b", "system",
13908                                 "-b", "main", "-b", "crash", "-t", String.valueOf(lines))
13909                                         .redirectErrorStream(true).start();
13910
13911                         try { logcat.getOutputStream().close(); } catch (IOException e) {}
13912                         try { logcat.getErrorStream().close(); } catch (IOException e) {}
13913                         input = new InputStreamReader(logcat.getInputStream());
13914
13915                         int num;
13916                         char[] buf = new char[8192];
13917                         while ((num = input.read(buf)) > 0) sb.append(buf, 0, num);
13918                     } catch (IOException e) {
13919                         Slog.e(TAG, "Error running logcat", e);
13920                     } finally {
13921                         if (input != null) try { input.close(); } catch (IOException e) {}
13922                     }
13923                 }
13924
13925                 dbox.addText(dropboxTag, sb.toString());
13926             }
13927         };
13928
13929         if (process == null) {
13930             // If process is null, we are being called from some internal code
13931             // and may be about to die -- run this synchronously.
13932             worker.run();
13933         } else {
13934             worker.start();
13935         }
13936     }
13937
13938     @Override
13939     public List<ActivityManager.ProcessErrorStateInfo> getProcessesInErrorState() {
13940         enforceNotIsolatedCaller("getProcessesInErrorState");
13941         // assume our apps are happy - lazy create the list
13942         List<ActivityManager.ProcessErrorStateInfo> errList = null;
13943
13944         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
13945                 Binder.getCallingUid()) == PackageManager.PERMISSION_GRANTED;
13946         int userId = UserHandle.getUserId(Binder.getCallingUid());
13947
13948         synchronized (this) {
13949
13950             // iterate across all processes
13951             for (int i=mLruProcesses.size()-1; i>=0; i--) {
13952                 ProcessRecord app = mLruProcesses.get(i);
13953                 if (!allUsers && app.userId != userId) {
13954                     continue;
13955                 }
13956                 if ((app.thread != null) && (app.crashing || app.notResponding)) {
13957                     // This one's in trouble, so we'll generate a report for it
13958                     // crashes are higher priority (in case there's a crash *and* an anr)
13959                     ActivityManager.ProcessErrorStateInfo report = null;
13960                     if (app.crashing) {
13961                         report = app.crashingReport;
13962                     } else if (app.notResponding) {
13963                         report = app.notRespondingReport;
13964                     }
13965
13966                     if (report != null) {
13967                         if (errList == null) {
13968                             errList = new ArrayList<ActivityManager.ProcessErrorStateInfo>(1);
13969                         }
13970                         errList.add(report);
13971                     } else {
13972                         Slog.w(TAG, "Missing app error report, app = " + app.processName +
13973                                 " crashing = " + app.crashing +
13974                                 " notResponding = " + app.notResponding);
13975                     }
13976                 }
13977             }
13978         }
13979
13980         return errList;
13981     }
13982
13983     static int procStateToImportance(int procState, int memAdj,
13984             ActivityManager.RunningAppProcessInfo currApp) {
13985         int imp = ActivityManager.RunningAppProcessInfo.procStateToImportance(procState);
13986         if (imp == ActivityManager.RunningAppProcessInfo.IMPORTANCE_BACKGROUND) {
13987             currApp.lru = memAdj;
13988         } else {
13989             currApp.lru = 0;
13990         }
13991         return imp;
13992     }
13993
13994     private void fillInProcMemInfo(ProcessRecord app,
13995             ActivityManager.RunningAppProcessInfo outInfo) {
13996         outInfo.pid = app.pid;
13997         outInfo.uid = app.info.uid;
13998         if (mHeavyWeightProcess == app) {
13999             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_CANT_SAVE_STATE;
14000         }
14001         if (app.persistent) {
14002             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_PERSISTENT;
14003         }
14004         if (app.activities.size() > 0) {
14005             outInfo.flags |= ActivityManager.RunningAppProcessInfo.FLAG_HAS_ACTIVITIES;
14006         }
14007         outInfo.lastTrimLevel = app.trimMemoryLevel;
14008         int adj = app.curAdj;
14009         int procState = app.curProcState;
14010         outInfo.importance = procStateToImportance(procState, adj, outInfo);
14011         outInfo.importanceReasonCode = app.adjTypeCode;
14012         outInfo.processState = app.curProcState;
14013     }
14014
14015     @Override
14016     public List<ActivityManager.RunningAppProcessInfo> getRunningAppProcesses() {
14017         enforceNotIsolatedCaller("getRunningAppProcesses");
14018
14019         final int callingUid = Binder.getCallingUid();
14020
14021         // Lazy instantiation of list
14022         List<ActivityManager.RunningAppProcessInfo> runList = null;
14023         final boolean allUsers = ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL,
14024                 callingUid) == PackageManager.PERMISSION_GRANTED;
14025         final int userId = UserHandle.getUserId(callingUid);
14026         final boolean allUids = isGetTasksAllowed(
14027                 "getRunningAppProcesses", Binder.getCallingPid(), callingUid);
14028
14029         synchronized (this) {
14030             // Iterate across all processes
14031             for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
14032                 ProcessRecord app = mLruProcesses.get(i);
14033                 if ((!allUsers && app.userId != userId)
14034                         || (!allUids && app.uid != callingUid)) {
14035                     continue;
14036                 }
14037                 if ((app.thread != null) && (!app.crashing && !app.notResponding)) {
14038                     // Generate process state info for running application
14039                     ActivityManager.RunningAppProcessInfo currApp =
14040                         new ActivityManager.RunningAppProcessInfo(app.processName,
14041                                 app.pid, app.getPackageList());
14042                     fillInProcMemInfo(app, currApp);
14043                     if (app.adjSource instanceof ProcessRecord) {
14044                         currApp.importanceReasonPid = ((ProcessRecord)app.adjSource).pid;
14045                         currApp.importanceReasonImportance =
14046                                 ActivityManager.RunningAppProcessInfo.procStateToImportance(
14047                                         app.adjSourceProcState);
14048                     } else if (app.adjSource instanceof ActivityRecord) {
14049                         ActivityRecord r = (ActivityRecord)app.adjSource;
14050                         if (r.app != null) currApp.importanceReasonPid = r.app.pid;
14051                     }
14052                     if (app.adjTarget instanceof ComponentName) {
14053                         currApp.importanceReasonComponent = (ComponentName)app.adjTarget;
14054                     }
14055                     //Slog.v(TAG, "Proc " + app.processName + ": imp=" + currApp.importance
14056                     //        + " lru=" + currApp.lru);
14057                     if (runList == null) {
14058                         runList = new ArrayList<>();
14059                     }
14060                     runList.add(currApp);
14061                 }
14062             }
14063         }
14064         return runList;
14065     }
14066
14067     @Override
14068     public List<ApplicationInfo> getRunningExternalApplications() {
14069         enforceNotIsolatedCaller("getRunningExternalApplications");
14070         List<ActivityManager.RunningAppProcessInfo> runningApps = getRunningAppProcesses();
14071         List<ApplicationInfo> retList = new ArrayList<ApplicationInfo>();
14072         if (runningApps != null && runningApps.size() > 0) {
14073             Set<String> extList = new HashSet<String>();
14074             for (ActivityManager.RunningAppProcessInfo app : runningApps) {
14075                 if (app.pkgList != null) {
14076                     for (String pkg : app.pkgList) {
14077                         extList.add(pkg);
14078                     }
14079                 }
14080             }
14081             IPackageManager pm = AppGlobals.getPackageManager();
14082             for (String pkg : extList) {
14083                 try {
14084                     ApplicationInfo info = pm.getApplicationInfo(pkg, 0, UserHandle.getCallingUserId());
14085                     if ((info.flags & ApplicationInfo.FLAG_EXTERNAL_STORAGE) != 0) {
14086                         retList.add(info);
14087                     }
14088                 } catch (RemoteException e) {
14089                 }
14090             }
14091         }
14092         return retList;
14093     }
14094
14095     @Override
14096     public void getMyMemoryState(ActivityManager.RunningAppProcessInfo outInfo) {
14097         enforceNotIsolatedCaller("getMyMemoryState");
14098         synchronized (this) {
14099             ProcessRecord proc;
14100             synchronized (mPidsSelfLocked) {
14101                 proc = mPidsSelfLocked.get(Binder.getCallingPid());
14102             }
14103             fillInProcMemInfo(proc, outInfo);
14104         }
14105     }
14106
14107     @Override
14108     public int getMemoryTrimLevel() {
14109         enforceNotIsolatedCaller("getMyMemoryState");
14110         synchronized (this) {
14111             return mLastMemoryLevel;
14112         }
14113     }
14114
14115     @Override
14116     public void onShellCommand(FileDescriptor in, FileDescriptor out,
14117             FileDescriptor err, String[] args, ResultReceiver resultReceiver) {
14118         (new ActivityManagerShellCommand(this, false)).exec(
14119                 this, in, out, err, args, resultReceiver);
14120     }
14121
14122     @Override
14123     protected void dump(FileDescriptor fd, PrintWriter pw, String[] args) {
14124         if (checkCallingPermission(android.Manifest.permission.DUMP)
14125                 != PackageManager.PERMISSION_GRANTED) {
14126             pw.println("Permission Denial: can't dump ActivityManager from from pid="
14127                     + Binder.getCallingPid()
14128                     + ", uid=" + Binder.getCallingUid()
14129                     + " without permission "
14130                     + android.Manifest.permission.DUMP);
14131             return;
14132         }
14133
14134         boolean dumpAll = false;
14135         boolean dumpClient = false;
14136         boolean dumpCheckin = false;
14137         boolean dumpCheckinFormat = false;
14138         String dumpPackage = null;
14139
14140         int opti = 0;
14141         while (opti < args.length) {
14142             String opt = args[opti];
14143             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
14144                 break;
14145             }
14146             opti++;
14147             if ("-a".equals(opt)) {
14148                 dumpAll = true;
14149             } else if ("-c".equals(opt)) {
14150                 dumpClient = true;
14151             } else if ("-p".equals(opt)) {
14152                 if (opti < args.length) {
14153                     dumpPackage = args[opti];
14154                     opti++;
14155                 } else {
14156                     pw.println("Error: -p option requires package argument");
14157                     return;
14158                 }
14159                 dumpClient = true;
14160             } else if ("--checkin".equals(opt)) {
14161                 dumpCheckin = dumpCheckinFormat = true;
14162             } else if ("-C".equals(opt)) {
14163                 dumpCheckinFormat = true;
14164             } else if ("-h".equals(opt)) {
14165                 ActivityManagerShellCommand.dumpHelp(pw, true);
14166                 return;
14167             } else {
14168                 pw.println("Unknown argument: " + opt + "; use -h for help");
14169             }
14170         }
14171
14172         long origId = Binder.clearCallingIdentity();
14173         boolean more = false;
14174         // Is the caller requesting to dump a particular piece of data?
14175         if (opti < args.length) {
14176             String cmd = args[opti];
14177             opti++;
14178             if ("activities".equals(cmd) || "a".equals(cmd)) {
14179                 synchronized (this) {
14180                     dumpActivitiesLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14181                 }
14182             } else if ("recents".equals(cmd) || "r".equals(cmd)) {
14183                 synchronized (this) {
14184                     dumpRecentsLocked(fd, pw, args, opti, true, dumpPackage);
14185                 }
14186             } else if ("broadcasts".equals(cmd) || "b".equals(cmd)) {
14187                 String[] newArgs;
14188                 String name;
14189                 if (opti >= args.length) {
14190                     name = null;
14191                     newArgs = EMPTY_STRING_ARRAY;
14192                 } else {
14193                     dumpPackage = args[opti];
14194                     opti++;
14195                     newArgs = new String[args.length - opti];
14196                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14197                             args.length - opti);
14198                 }
14199                 synchronized (this) {
14200                     dumpBroadcastsLocked(fd, pw, args, opti, true, dumpPackage);
14201                 }
14202             } else if ("broadcast-stats".equals(cmd)) {
14203                 String[] newArgs;
14204                 String name;
14205                 if (opti >= args.length) {
14206                     name = null;
14207                     newArgs = EMPTY_STRING_ARRAY;
14208                 } else {
14209                     dumpPackage = args[opti];
14210                     opti++;
14211                     newArgs = new String[args.length - opti];
14212                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14213                             args.length - opti);
14214                 }
14215                 synchronized (this) {
14216                     if (dumpCheckinFormat) {
14217                         dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin,
14218                                 dumpPackage);
14219                     } else {
14220                         dumpBroadcastStatsLocked(fd, pw, args, opti, true, dumpPackage);
14221                     }
14222                 }
14223             } else if ("intents".equals(cmd) || "i".equals(cmd)) {
14224                 String[] newArgs;
14225                 String name;
14226                 if (opti >= args.length) {
14227                     name = null;
14228                     newArgs = EMPTY_STRING_ARRAY;
14229                 } else {
14230                     dumpPackage = args[opti];
14231                     opti++;
14232                     newArgs = new String[args.length - opti];
14233                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14234                             args.length - opti);
14235                 }
14236                 synchronized (this) {
14237                     dumpPendingIntentsLocked(fd, pw, args, opti, true, dumpPackage);
14238                 }
14239             } else if ("processes".equals(cmd) || "p".equals(cmd)) {
14240                 String[] newArgs;
14241                 String name;
14242                 if (opti >= args.length) {
14243                     name = null;
14244                     newArgs = EMPTY_STRING_ARRAY;
14245                 } else {
14246                     dumpPackage = args[opti];
14247                     opti++;
14248                     newArgs = new String[args.length - opti];
14249                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14250                             args.length - opti);
14251                 }
14252                 synchronized (this) {
14253                     dumpProcessesLocked(fd, pw, args, opti, true, dumpPackage);
14254                 }
14255             } else if ("oom".equals(cmd) || "o".equals(cmd)) {
14256                 synchronized (this) {
14257                     dumpOomLocked(fd, pw, args, opti, true);
14258                 }
14259             } else if ("permissions".equals(cmd) || "perm".equals(cmd)) {
14260                 synchronized (this) {
14261                     dumpPermissionsLocked(fd, pw, args, opti, true, null);
14262                 }
14263             } else if ("provider".equals(cmd)) {
14264                 String[] newArgs;
14265                 String name;
14266                 if (opti >= args.length) {
14267                     name = null;
14268                     newArgs = EMPTY_STRING_ARRAY;
14269                 } else {
14270                     name = args[opti];
14271                     opti++;
14272                     newArgs = new String[args.length - opti];
14273                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0, args.length - opti);
14274                 }
14275                 if (!dumpProvider(fd, pw, name, newArgs, 0, dumpAll)) {
14276                     pw.println("No providers match: " + name);
14277                     pw.println("Use -h for help.");
14278                 }
14279             } else if ("providers".equals(cmd) || "prov".equals(cmd)) {
14280                 synchronized (this) {
14281                     dumpProvidersLocked(fd, pw, args, opti, true, null);
14282                 }
14283             } else if ("service".equals(cmd)) {
14284                 String[] newArgs;
14285                 String name;
14286                 if (opti >= args.length) {
14287                     name = null;
14288                     newArgs = EMPTY_STRING_ARRAY;
14289                 } else {
14290                     name = args[opti];
14291                     opti++;
14292                     newArgs = new String[args.length - opti];
14293                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14294                             args.length - opti);
14295                 }
14296                 if (!mServices.dumpService(fd, pw, name, newArgs, 0, dumpAll)) {
14297                     pw.println("No services match: " + name);
14298                     pw.println("Use -h for help.");
14299                 }
14300             } else if ("package".equals(cmd)) {
14301                 String[] newArgs;
14302                 if (opti >= args.length) {
14303                     pw.println("package: no package name specified");
14304                     pw.println("Use -h for help.");
14305                 } else {
14306                     dumpPackage = args[opti];
14307                     opti++;
14308                     newArgs = new String[args.length - opti];
14309                     if (args.length > 2) System.arraycopy(args, opti, newArgs, 0,
14310                             args.length - opti);
14311                     args = newArgs;
14312                     opti = 0;
14313                     more = true;
14314                 }
14315             } else if ("associations".equals(cmd) || "as".equals(cmd)) {
14316                 synchronized (this) {
14317                     dumpAssociationsLocked(fd, pw, args, opti, true, dumpClient, dumpPackage);
14318                 }
14319             } else if ("services".equals(cmd) || "s".equals(cmd)) {
14320                 if (dumpClient) {
14321                     ActiveServices.ServiceDumper dumper;
14322                     synchronized (this) {
14323                         dumper = mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14324                                 dumpPackage);
14325                     }
14326                     dumper.dumpWithClient();
14327                 } else {
14328                     synchronized (this) {
14329                         mServices.newServiceDumperLocked(fd, pw, args, opti, true,
14330                                 dumpPackage).dumpLocked();
14331                     }
14332                 }
14333             } else if ("locks".equals(cmd)) {
14334                 LockGuard.dump(fd, pw, args);
14335             } else {
14336                 // Dumping a single activity?
14337                 if (!dumpActivity(fd, pw, cmd, args, opti, dumpAll)) {
14338                     ActivityManagerShellCommand shell = new ActivityManagerShellCommand(this, true);
14339                     int res = shell.exec(this, null, fd, null, args, new ResultReceiver(null));
14340                     if (res < 0) {
14341                         pw.println("Bad activity command, or no activities match: " + cmd);
14342                         pw.println("Use -h for help.");
14343                     }
14344                 }
14345             }
14346             if (!more) {
14347                 Binder.restoreCallingIdentity(origId);
14348                 return;
14349             }
14350         }
14351
14352         // No piece of data specified, dump everything.
14353         if (dumpCheckinFormat) {
14354             dumpBroadcastStatsCheckinLocked(fd, pw, args, opti, dumpCheckin, dumpPackage);
14355         } else if (dumpClient) {
14356             ActiveServices.ServiceDumper sdumper;
14357             synchronized (this) {
14358                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14359                 pw.println();
14360                 if (dumpAll) {
14361                     pw.println("-------------------------------------------------------------------------------");
14362                 }
14363                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14364                 pw.println();
14365                 if (dumpAll) {
14366                     pw.println("-------------------------------------------------------------------------------");
14367                 }
14368                 if (dumpAll || dumpPackage != null) {
14369                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14370                     pw.println();
14371                     if (dumpAll) {
14372                         pw.println("-------------------------------------------------------------------------------");
14373                     }
14374                 }
14375                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14376                 pw.println();
14377                 if (dumpAll) {
14378                     pw.println("-------------------------------------------------------------------------------");
14379                 }
14380                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14381                 pw.println();
14382                 if (dumpAll) {
14383                     pw.println("-------------------------------------------------------------------------------");
14384                 }
14385                 sdumper = mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll,
14386                         dumpPackage);
14387             }
14388             sdumper.dumpWithClient();
14389             pw.println();
14390             synchronized (this) {
14391                 if (dumpAll) {
14392                     pw.println("-------------------------------------------------------------------------------");
14393                 }
14394                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14395                 pw.println();
14396                 if (dumpAll) {
14397                     pw.println("-------------------------------------------------------------------------------");
14398                 }
14399                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14400                 if (mAssociations.size() > 0) {
14401                     pw.println();
14402                     if (dumpAll) {
14403                         pw.println("-------------------------------------------------------------------------------");
14404                     }
14405                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14406                 }
14407                 pw.println();
14408                 if (dumpAll) {
14409                     pw.println("-------------------------------------------------------------------------------");
14410                 }
14411                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14412             }
14413
14414         } else {
14415             synchronized (this) {
14416                 dumpPendingIntentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14417                 pw.println();
14418                 if (dumpAll) {
14419                     pw.println("-------------------------------------------------------------------------------");
14420                 }
14421                 dumpBroadcastsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14422                 pw.println();
14423                 if (dumpAll) {
14424                     pw.println("-------------------------------------------------------------------------------");
14425                 }
14426                 if (dumpAll || dumpPackage != null) {
14427                     dumpBroadcastStatsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14428                     pw.println();
14429                     if (dumpAll) {
14430                         pw.println("-------------------------------------------------------------------------------");
14431                     }
14432                 }
14433                 dumpProvidersLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14434                 pw.println();
14435                 if (dumpAll) {
14436                     pw.println("-------------------------------------------------------------------------------");
14437                 }
14438                 dumpPermissionsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14439                 pw.println();
14440                 if (dumpAll) {
14441                     pw.println("-------------------------------------------------------------------------------");
14442                 }
14443                 mServices.newServiceDumperLocked(fd, pw, args, opti, dumpAll, dumpPackage)
14444                         .dumpLocked();
14445                 pw.println();
14446                 if (dumpAll) {
14447                     pw.println("-------------------------------------------------------------------------------");
14448                 }
14449                 dumpRecentsLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14450                 pw.println();
14451                 if (dumpAll) {
14452                     pw.println("-------------------------------------------------------------------------------");
14453                 }
14454                 dumpActivitiesLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14455                 if (mAssociations.size() > 0) {
14456                     pw.println();
14457                     if (dumpAll) {
14458                         pw.println("-------------------------------------------------------------------------------");
14459                     }
14460                     dumpAssociationsLocked(fd, pw, args, opti, dumpAll, dumpClient, dumpPackage);
14461                 }
14462                 pw.println();
14463                 if (dumpAll) {
14464                     pw.println("-------------------------------------------------------------------------------");
14465                 }
14466                 dumpProcessesLocked(fd, pw, args, opti, dumpAll, dumpPackage);
14467             }
14468         }
14469         Binder.restoreCallingIdentity(origId);
14470     }
14471
14472     void dumpActivitiesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14473             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14474         pw.println("ACTIVITY MANAGER ACTIVITIES (dumpsys activity activities)");
14475
14476         boolean printedAnything = mStackSupervisor.dumpActivitiesLocked(fd, pw, dumpAll, dumpClient,
14477                 dumpPackage);
14478         boolean needSep = printedAnything;
14479
14480         boolean printed = ActivityStackSupervisor.printThisActivity(pw, mFocusedActivity,
14481                 dumpPackage, needSep, "  mFocusedActivity: ");
14482         if (printed) {
14483             printedAnything = true;
14484             needSep = false;
14485         }
14486
14487         if (dumpPackage == null) {
14488             if (needSep) {
14489                 pw.println();
14490             }
14491             needSep = true;
14492             printedAnything = true;
14493             mStackSupervisor.dump(pw, "  ");
14494         }
14495
14496         if (!printedAnything) {
14497             pw.println("  (nothing)");
14498         }
14499     }
14500
14501     void dumpRecentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14502             int opti, boolean dumpAll, String dumpPackage) {
14503         pw.println("ACTIVITY MANAGER RECENT TASKS (dumpsys activity recents)");
14504
14505         boolean printedAnything = false;
14506
14507         if (mRecentTasks != null && mRecentTasks.size() > 0) {
14508             boolean printedHeader = false;
14509
14510             final int N = mRecentTasks.size();
14511             for (int i=0; i<N; i++) {
14512                 TaskRecord tr = mRecentTasks.get(i);
14513                 if (dumpPackage != null) {
14514                     if (tr.realActivity == null ||
14515                             !dumpPackage.equals(tr.realActivity)) {
14516                         continue;
14517                     }
14518                 }
14519                 if (!printedHeader) {
14520                     pw.println("  Recent tasks:");
14521                     printedHeader = true;
14522                     printedAnything = true;
14523                 }
14524                 pw.print("  * Recent #"); pw.print(i); pw.print(": ");
14525                         pw.println(tr);
14526                 if (dumpAll) {
14527                     mRecentTasks.get(i).dump(pw, "    ");
14528                 }
14529             }
14530         }
14531
14532         if (!printedAnything) {
14533             pw.println("  (nothing)");
14534         }
14535     }
14536
14537     void dumpAssociationsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14538             int opti, boolean dumpAll, boolean dumpClient, String dumpPackage) {
14539         pw.println("ACTIVITY MANAGER ASSOCIATIONS (dumpsys activity associations)");
14540
14541         int dumpUid = 0;
14542         if (dumpPackage != null) {
14543             IPackageManager pm = AppGlobals.getPackageManager();
14544             try {
14545                 dumpUid = pm.getPackageUid(dumpPackage, MATCH_UNINSTALLED_PACKAGES, 0);
14546             } catch (RemoteException e) {
14547             }
14548         }
14549
14550         boolean printedAnything = false;
14551
14552         final long now = SystemClock.uptimeMillis();
14553
14554         for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
14555             ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
14556                     = mAssociations.valueAt(i1);
14557             for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
14558                 SparseArray<ArrayMap<String, Association>> sourceUids
14559                         = targetComponents.valueAt(i2);
14560                 for (int i3=0, N3=sourceUids.size(); i3<N3; i3++) {
14561                     ArrayMap<String, Association> sourceProcesses = sourceUids.valueAt(i3);
14562                     for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
14563                         Association ass = sourceProcesses.valueAt(i4);
14564                         if (dumpPackage != null) {
14565                             if (!ass.mTargetComponent.getPackageName().equals(dumpPackage)
14566                                     && UserHandle.getAppId(ass.mSourceUid) != dumpUid) {
14567                                 continue;
14568                             }
14569                         }
14570                         printedAnything = true;
14571                         pw.print("  ");
14572                         pw.print(ass.mTargetProcess);
14573                         pw.print("/");
14574                         UserHandle.formatUid(pw, ass.mTargetUid);
14575                         pw.print(" <- ");
14576                         pw.print(ass.mSourceProcess);
14577                         pw.print("/");
14578                         UserHandle.formatUid(pw, ass.mSourceUid);
14579                         pw.println();
14580                         pw.print("    via ");
14581                         pw.print(ass.mTargetComponent.flattenToShortString());
14582                         pw.println();
14583                         pw.print("    ");
14584                         long dur = ass.mTime;
14585                         if (ass.mNesting > 0) {
14586                             dur += now - ass.mStartTime;
14587                         }
14588                         TimeUtils.formatDuration(dur, pw);
14589                         pw.print(" (");
14590                         pw.print(ass.mCount);
14591                         pw.print(" times)");
14592                         pw.print("  ");
14593                         for (int i=0; i<ass.mStateTimes.length; i++) {
14594                             long amt = ass.mStateTimes[i];
14595                             if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14596                                 amt += now - ass.mLastStateUptime;
14597                             }
14598                             if (amt != 0) {
14599                                 pw.print(" ");
14600                                 pw.print(ProcessList.makeProcStateString(
14601                                             i + ActivityManager.MIN_PROCESS_STATE));
14602                                 pw.print("=");
14603                                 TimeUtils.formatDuration(amt, pw);
14604                                 if (ass.mLastState-ActivityManager.MIN_PROCESS_STATE == i) {
14605                                     pw.print("*");
14606                                 }
14607                             }
14608                         }
14609                         pw.println();
14610                         if (ass.mNesting > 0) {
14611                             pw.print("    Currently active: ");
14612                             TimeUtils.formatDuration(now - ass.mStartTime, pw);
14613                             pw.println();
14614                         }
14615                     }
14616                 }
14617             }
14618
14619         }
14620
14621         if (!printedAnything) {
14622             pw.println("  (nothing)");
14623         }
14624     }
14625
14626     boolean dumpUids(PrintWriter pw, String dumpPackage, SparseArray<UidRecord> uids,
14627             String header, boolean needSep) {
14628         boolean printed = false;
14629         int whichAppId = -1;
14630         if (dumpPackage != null) {
14631             try {
14632                 ApplicationInfo info = mContext.getPackageManager().getApplicationInfo(
14633                         dumpPackage, 0);
14634                 whichAppId = UserHandle.getAppId(info.uid);
14635             } catch (NameNotFoundException e) {
14636                 e.printStackTrace();
14637             }
14638         }
14639         for (int i=0; i<uids.size(); i++) {
14640             UidRecord uidRec = uids.valueAt(i);
14641             if (dumpPackage != null && UserHandle.getAppId(uidRec.uid) != whichAppId) {
14642                 continue;
14643             }
14644             if (!printed) {
14645                 printed = true;
14646                 if (needSep) {
14647                     pw.println();
14648                 }
14649                 pw.print("  ");
14650                 pw.println(header);
14651                 needSep = true;
14652             }
14653             pw.print("    UID "); UserHandle.formatUid(pw, uidRec.uid);
14654             pw.print(": "); pw.println(uidRec);
14655         }
14656         return printed;
14657     }
14658
14659     void dumpProcessesLocked(FileDescriptor fd, PrintWriter pw, String[] args,
14660             int opti, boolean dumpAll, String dumpPackage) {
14661         boolean needSep = false;
14662         boolean printedAnything = false;
14663         int numPers = 0;
14664
14665         pw.println("ACTIVITY MANAGER RUNNING PROCESSES (dumpsys activity processes)");
14666
14667         if (dumpAll) {
14668             final int NP = mProcessNames.getMap().size();
14669             for (int ip=0; ip<NP; ip++) {
14670                 SparseArray<ProcessRecord> procs = mProcessNames.getMap().valueAt(ip);
14671                 final int NA = procs.size();
14672                 for (int ia=0; ia<NA; ia++) {
14673                     ProcessRecord r = procs.valueAt(ia);
14674                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14675                         continue;
14676                     }
14677                     if (!needSep) {
14678                         pw.println("  All known processes:");
14679                         needSep = true;
14680                         printedAnything = true;
14681                     }
14682                     pw.print(r.persistent ? "  *PERS*" : "  *APP*");
14683                         pw.print(" UID "); pw.print(procs.keyAt(ia));
14684                         pw.print(" "); pw.println(r);
14685                     r.dump(pw, "    ");
14686                     if (r.persistent) {
14687                         numPers++;
14688                     }
14689                 }
14690             }
14691         }
14692
14693         if (mIsolatedProcesses.size() > 0) {
14694             boolean printed = false;
14695             for (int i=0; i<mIsolatedProcesses.size(); i++) {
14696                 ProcessRecord r = mIsolatedProcesses.valueAt(i);
14697                 if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14698                     continue;
14699                 }
14700                 if (!printed) {
14701                     if (needSep) {
14702                         pw.println();
14703                     }
14704                     pw.println("  Isolated process list (sorted by uid):");
14705                     printedAnything = true;
14706                     printed = true;
14707                     needSep = true;
14708                 }
14709                 pw.println(String.format("%sIsolated #%2d: %s",
14710                         "    ", i, r.toString()));
14711             }
14712         }
14713
14714         if (mActiveUids.size() > 0) {
14715             if (dumpUids(pw, dumpPackage, mActiveUids, "UID states:", needSep)) {
14716                 printedAnything = needSep = true;
14717             }
14718         }
14719         if (mValidateUids.size() > 0) {
14720             if (dumpUids(pw, dumpPackage, mValidateUids, "UID validation:", needSep)) {
14721                 printedAnything = needSep = true;
14722             }
14723         }
14724
14725         if (mLruProcesses.size() > 0) {
14726             if (needSep) {
14727                 pw.println();
14728             }
14729             pw.print("  Process LRU list (sorted by oom_adj, "); pw.print(mLruProcesses.size());
14730                     pw.print(" total, non-act at ");
14731                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
14732                     pw.print(", non-svc at ");
14733                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
14734                     pw.println("):");
14735             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", false, dumpPackage);
14736             needSep = true;
14737             printedAnything = true;
14738         }
14739
14740         if (dumpAll || dumpPackage != null) {
14741             synchronized (mPidsSelfLocked) {
14742                 boolean printed = false;
14743                 for (int i=0; i<mPidsSelfLocked.size(); i++) {
14744                     ProcessRecord r = mPidsSelfLocked.valueAt(i);
14745                     if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
14746                         continue;
14747                     }
14748                     if (!printed) {
14749                         if (needSep) pw.println();
14750                         needSep = true;
14751                         pw.println("  PID mappings:");
14752                         printed = true;
14753                         printedAnything = true;
14754                     }
14755                     pw.print("    PID #"); pw.print(mPidsSelfLocked.keyAt(i));
14756                         pw.print(": "); pw.println(mPidsSelfLocked.valueAt(i));
14757                 }
14758             }
14759         }
14760
14761         if (mForegroundProcesses.size() > 0) {
14762             synchronized (mPidsSelfLocked) {
14763                 boolean printed = false;
14764                 for (int i=0; i<mForegroundProcesses.size(); i++) {
14765                     ProcessRecord r = mPidsSelfLocked.get(
14766                             mForegroundProcesses.valueAt(i).pid);
14767                     if (dumpPackage != null && (r == null
14768                             || !r.pkgList.containsKey(dumpPackage))) {
14769                         continue;
14770                     }
14771                     if (!printed) {
14772                         if (needSep) pw.println();
14773                         needSep = true;
14774                         pw.println("  Foreground Processes:");
14775                         printed = true;
14776                         printedAnything = true;
14777                     }
14778                     pw.print("    PID #"); pw.print(mForegroundProcesses.keyAt(i));
14779                             pw.print(": "); pw.println(mForegroundProcesses.valueAt(i));
14780                 }
14781             }
14782         }
14783
14784         if (mPersistentStartingProcesses.size() > 0) {
14785             if (needSep) pw.println();
14786             needSep = true;
14787             printedAnything = true;
14788             pw.println("  Persisent processes that are starting:");
14789             dumpProcessList(pw, this, mPersistentStartingProcesses, "    ",
14790                     "Starting Norm", "Restarting PERS", dumpPackage);
14791         }
14792
14793         if (mRemovedProcesses.size() > 0) {
14794             if (needSep) pw.println();
14795             needSep = true;
14796             printedAnything = true;
14797             pw.println("  Processes that are being removed:");
14798             dumpProcessList(pw, this, mRemovedProcesses, "    ",
14799                     "Removed Norm", "Removed PERS", dumpPackage);
14800         }
14801
14802         if (mProcessesOnHold.size() > 0) {
14803             if (needSep) pw.println();
14804             needSep = true;
14805             printedAnything = true;
14806             pw.println("  Processes that are on old until the system is ready:");
14807             dumpProcessList(pw, this, mProcessesOnHold, "    ",
14808                     "OnHold Norm", "OnHold PERS", dumpPackage);
14809         }
14810
14811         needSep = dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, dumpPackage);
14812
14813         needSep = mAppErrors.dumpLocked(fd, pw, needSep, dumpPackage);
14814         if (needSep) {
14815             printedAnything = true;
14816         }
14817
14818         if (dumpPackage == null) {
14819             pw.println();
14820             needSep = false;
14821             mUserController.dump(pw, dumpAll);
14822         }
14823         if (mHomeProcess != null && (dumpPackage == null
14824                 || mHomeProcess.pkgList.containsKey(dumpPackage))) {
14825             if (needSep) {
14826                 pw.println();
14827                 needSep = false;
14828             }
14829             pw.println("  mHomeProcess: " + mHomeProcess);
14830         }
14831         if (mPreviousProcess != null && (dumpPackage == null
14832                 || mPreviousProcess.pkgList.containsKey(dumpPackage))) {
14833             if (needSep) {
14834                 pw.println();
14835                 needSep = false;
14836             }
14837             pw.println("  mPreviousProcess: " + mPreviousProcess);
14838         }
14839         if (dumpAll) {
14840             StringBuilder sb = new StringBuilder(128);
14841             sb.append("  mPreviousProcessVisibleTime: ");
14842             TimeUtils.formatDuration(mPreviousProcessVisibleTime, sb);
14843             pw.println(sb);
14844         }
14845         if (mHeavyWeightProcess != null && (dumpPackage == null
14846                 || mHeavyWeightProcess.pkgList.containsKey(dumpPackage))) {
14847             if (needSep) {
14848                 pw.println();
14849                 needSep = false;
14850             }
14851             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
14852         }
14853         if (dumpPackage == null) {
14854             pw.println("  mConfiguration: " + mConfiguration);
14855         }
14856         if (dumpAll) {
14857             pw.println("  mConfigWillChange: " + getFocusedStack().mConfigWillChange);
14858             if (mCompatModePackages.getPackages().size() > 0) {
14859                 boolean printed = false;
14860                 for (Map.Entry<String, Integer> entry
14861                         : mCompatModePackages.getPackages().entrySet()) {
14862                     String pkg = entry.getKey();
14863                     int mode = entry.getValue();
14864                     if (dumpPackage != null && !dumpPackage.equals(pkg)) {
14865                         continue;
14866                     }
14867                     if (!printed) {
14868                         pw.println("  mScreenCompatPackages:");
14869                         printed = true;
14870                     }
14871                     pw.print("    "); pw.print(pkg); pw.print(": ");
14872                             pw.print(mode); pw.println();
14873                 }
14874             }
14875         }
14876         if (dumpPackage == null) {
14877             pw.println("  mWakefulness="
14878                     + PowerManagerInternal.wakefulnessToString(mWakefulness));
14879             pw.println("  mSleepTokens=" + mSleepTokens);
14880             pw.println("  mSleeping=" + mSleeping + " mLockScreenShown="
14881                     + lockScreenShownToString());
14882             pw.println("  mShuttingDown=" + mShuttingDown + " mTestPssMode=" + mTestPssMode);
14883             if (mRunningVoice != null) {
14884                 pw.println("  mRunningVoice=" + mRunningVoice);
14885                 pw.println("  mVoiceWakeLock" + mVoiceWakeLock);
14886             }
14887         }
14888         if (mDebugApp != null || mOrigDebugApp != null || mDebugTransient
14889                 || mOrigWaitForDebugger) {
14890             if (dumpPackage == null || dumpPackage.equals(mDebugApp)
14891                     || dumpPackage.equals(mOrigDebugApp)) {
14892                 if (needSep) {
14893                     pw.println();
14894                     needSep = false;
14895                 }
14896                 pw.println("  mDebugApp=" + mDebugApp + "/orig=" + mOrigDebugApp
14897                         + " mDebugTransient=" + mDebugTransient
14898                         + " mOrigWaitForDebugger=" + mOrigWaitForDebugger);
14899             }
14900         }
14901         if (mCurAppTimeTracker != null) {
14902             mCurAppTimeTracker.dumpWithHeader(pw, "  ", true);
14903         }
14904         if (mMemWatchProcesses.getMap().size() > 0) {
14905             pw.println("  Mem watch processes:");
14906             final ArrayMap<String, SparseArray<Pair<Long, String>>> procs
14907                     = mMemWatchProcesses.getMap();
14908             for (int i=0; i<procs.size(); i++) {
14909                 final String proc = procs.keyAt(i);
14910                 final SparseArray<Pair<Long, String>> uids = procs.valueAt(i);
14911                 for (int j=0; j<uids.size(); j++) {
14912                     if (needSep) {
14913                         pw.println();
14914                         needSep = false;
14915                     }
14916                     StringBuilder sb = new StringBuilder();
14917                     sb.append("    ").append(proc).append('/');
14918                     UserHandle.formatUid(sb, uids.keyAt(j));
14919                     Pair<Long, String> val = uids.valueAt(j);
14920                     sb.append(": "); DebugUtils.sizeValueToString(val.first, sb);
14921                     if (val.second != null) {
14922                         sb.append(", report to ").append(val.second);
14923                     }
14924                     pw.println(sb.toString());
14925                 }
14926             }
14927             pw.print("  mMemWatchDumpProcName="); pw.println(mMemWatchDumpProcName);
14928             pw.print("  mMemWatchDumpFile="); pw.println(mMemWatchDumpFile);
14929             pw.print("  mMemWatchDumpPid="); pw.print(mMemWatchDumpPid);
14930                     pw.print(" mMemWatchDumpUid="); pw.println(mMemWatchDumpUid);
14931         }
14932         if (mTrackAllocationApp != null) {
14933             if (dumpPackage == null || dumpPackage.equals(mTrackAllocationApp)) {
14934                 if (needSep) {
14935                     pw.println();
14936                     needSep = false;
14937                 }
14938                 pw.println("  mTrackAllocationApp=" + mTrackAllocationApp);
14939             }
14940         }
14941         if (mProfileApp != null || mProfileProc != null || mProfileFile != null
14942                 || mProfileFd != null) {
14943             if (dumpPackage == null || dumpPackage.equals(mProfileApp)) {
14944                 if (needSep) {
14945                     pw.println();
14946                     needSep = false;
14947                 }
14948                 pw.println("  mProfileApp=" + mProfileApp + " mProfileProc=" + mProfileProc);
14949                 pw.println("  mProfileFile=" + mProfileFile + " mProfileFd=" + mProfileFd);
14950                 pw.println("  mSamplingInterval=" + mSamplingInterval + " mAutoStopProfiler="
14951                         + mAutoStopProfiler);
14952                 pw.println("  mProfileType=" + mProfileType);
14953             }
14954         }
14955         if (mNativeDebuggingApp != null) {
14956             if (dumpPackage == null || dumpPackage.equals(mNativeDebuggingApp)) {
14957                 if (needSep) {
14958                     pw.println();
14959                     needSep = false;
14960                 }
14961                 pw.println("  mNativeDebuggingApp=" + mNativeDebuggingApp);
14962             }
14963         }
14964         if (dumpPackage == null) {
14965             if (mAlwaysFinishActivities || mLenientBackgroundCheck) {
14966                 pw.println("  mAlwaysFinishActivities=" + mAlwaysFinishActivities
14967                         + " mLenientBackgroundCheck=" + mLenientBackgroundCheck);
14968             }
14969             if (mController != null) {
14970                 pw.println("  mController=" + mController
14971                         + " mControllerIsAMonkey=" + mControllerIsAMonkey);
14972             }
14973             if (dumpAll) {
14974                 pw.println("  Total persistent processes: " + numPers);
14975                 pw.println("  mProcessesReady=" + mProcessesReady
14976                         + " mSystemReady=" + mSystemReady
14977                         + " mBooted=" + mBooted
14978                         + " mFactoryTest=" + mFactoryTest);
14979                 pw.println("  mBooting=" + mBooting
14980                         + " mCallFinishBooting=" + mCallFinishBooting
14981                         + " mBootAnimationComplete=" + mBootAnimationComplete);
14982                 pw.print("  mLastPowerCheckRealtime=");
14983                         TimeUtils.formatDuration(mLastPowerCheckRealtime, pw);
14984                         pw.println("");
14985                 pw.print("  mLastPowerCheckUptime=");
14986                         TimeUtils.formatDuration(mLastPowerCheckUptime, pw);
14987                         pw.println("");
14988                 pw.println("  mGoingToSleep=" + mStackSupervisor.mGoingToSleep);
14989                 pw.println("  mLaunchingActivity=" + mStackSupervisor.mLaunchingActivity);
14990                 pw.println("  mAdjSeq=" + mAdjSeq + " mLruSeq=" + mLruSeq);
14991                 pw.println("  mNumNonCachedProcs=" + mNumNonCachedProcs
14992                         + " (" + mLruProcesses.size() + " total)"
14993                         + " mNumCachedHiddenProcs=" + mNumCachedHiddenProcs
14994                         + " mNumServiceProcs=" + mNumServiceProcs
14995                         + " mNewNumServiceProcs=" + mNewNumServiceProcs);
14996                 pw.println("  mAllowLowerMemLevel=" + mAllowLowerMemLevel
14997                         + " mLastMemoryLevel=" + mLastMemoryLevel
14998                         + " mLastNumProcesses=" + mLastNumProcesses);
14999                 long now = SystemClock.uptimeMillis();
15000                 pw.print("  mLastIdleTime=");
15001                         TimeUtils.formatDuration(now, mLastIdleTime, pw);
15002                         pw.print(" mLowRamSinceLastIdle=");
15003                         TimeUtils.formatDuration(getLowRamTimeSinceIdle(now), pw);
15004                         pw.println();
15005             }
15006         }
15007
15008         if (!printedAnything) {
15009             pw.println("  (nothing)");
15010         }
15011     }
15012
15013     boolean dumpProcessesToGc(FileDescriptor fd, PrintWriter pw, String[] args,
15014             int opti, boolean needSep, boolean dumpAll, String dumpPackage) {
15015         if (mProcessesToGc.size() > 0) {
15016             boolean printed = false;
15017             long now = SystemClock.uptimeMillis();
15018             for (int i=0; i<mProcessesToGc.size(); i++) {
15019                 ProcessRecord proc = mProcessesToGc.get(i);
15020                 if (dumpPackage != null && !dumpPackage.equals(proc.info.packageName)) {
15021                     continue;
15022                 }
15023                 if (!printed) {
15024                     if (needSep) pw.println();
15025                     needSep = true;
15026                     pw.println("  Processes that are waiting to GC:");
15027                     printed = true;
15028                 }
15029                 pw.print("    Process "); pw.println(proc);
15030                 pw.print("      lowMem="); pw.print(proc.reportLowMemory);
15031                         pw.print(", last gced=");
15032                         pw.print(now-proc.lastRequestedGc);
15033                         pw.print(" ms ago, last lowMem=");
15034                         pw.print(now-proc.lastLowMemory);
15035                         pw.println(" ms ago");
15036
15037             }
15038         }
15039         return needSep;
15040     }
15041
15042     void printOomLevel(PrintWriter pw, String name, int adj) {
15043         pw.print("    ");
15044         if (adj >= 0) {
15045             pw.print(' ');
15046             if (adj < 10) pw.print(' ');
15047         } else {
15048             if (adj > -10) pw.print(' ');
15049         }
15050         pw.print(adj);
15051         pw.print(": ");
15052         pw.print(name);
15053         pw.print(" (");
15054         pw.print(stringifySize(mProcessList.getMemLevel(adj), 1024));
15055         pw.println(")");
15056     }
15057
15058     boolean dumpOomLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15059             int opti, boolean dumpAll) {
15060         boolean needSep = false;
15061
15062         if (mLruProcesses.size() > 0) {
15063             if (needSep) pw.println();
15064             needSep = true;
15065             pw.println("  OOM levels:");
15066             printOomLevel(pw, "SYSTEM_ADJ", ProcessList.SYSTEM_ADJ);
15067             printOomLevel(pw, "PERSISTENT_PROC_ADJ", ProcessList.PERSISTENT_PROC_ADJ);
15068             printOomLevel(pw, "PERSISTENT_SERVICE_ADJ", ProcessList.PERSISTENT_SERVICE_ADJ);
15069             printOomLevel(pw, "FOREGROUND_APP_ADJ", ProcessList.FOREGROUND_APP_ADJ);
15070             printOomLevel(pw, "VISIBLE_APP_ADJ", ProcessList.VISIBLE_APP_ADJ);
15071             printOomLevel(pw, "PERCEPTIBLE_APP_ADJ", ProcessList.PERCEPTIBLE_APP_ADJ);
15072             printOomLevel(pw, "BACKUP_APP_ADJ", ProcessList.BACKUP_APP_ADJ);
15073             printOomLevel(pw, "HEAVY_WEIGHT_APP_ADJ", ProcessList.HEAVY_WEIGHT_APP_ADJ);
15074             printOomLevel(pw, "SERVICE_ADJ", ProcessList.SERVICE_ADJ);
15075             printOomLevel(pw, "HOME_APP_ADJ", ProcessList.HOME_APP_ADJ);
15076             printOomLevel(pw, "PREVIOUS_APP_ADJ", ProcessList.PREVIOUS_APP_ADJ);
15077             printOomLevel(pw, "SERVICE_B_ADJ", ProcessList.SERVICE_B_ADJ);
15078             printOomLevel(pw, "CACHED_APP_MIN_ADJ", ProcessList.CACHED_APP_MIN_ADJ);
15079             printOomLevel(pw, "CACHED_APP_MAX_ADJ", ProcessList.CACHED_APP_MAX_ADJ);
15080
15081             if (needSep) pw.println();
15082             pw.print("  Process OOM control ("); pw.print(mLruProcesses.size());
15083                     pw.print(" total, non-act at ");
15084                     pw.print(mLruProcesses.size()-mLruProcessActivityStart);
15085                     pw.print(", non-svc at ");
15086                     pw.print(mLruProcesses.size()-mLruProcessServiceStart);
15087                     pw.println("):");
15088             dumpProcessOomList(pw, this, mLruProcesses, "    ", "Proc", "PERS", true, null);
15089             needSep = true;
15090         }
15091
15092         dumpProcessesToGc(fd, pw, args, opti, needSep, dumpAll, null);
15093
15094         pw.println();
15095         pw.println("  mHomeProcess: " + mHomeProcess);
15096         pw.println("  mPreviousProcess: " + mPreviousProcess);
15097         if (mHeavyWeightProcess != null) {
15098             pw.println("  mHeavyWeightProcess: " + mHeavyWeightProcess);
15099         }
15100
15101         return true;
15102     }
15103
15104     /**
15105      * There are three ways to call this:
15106      *  - no provider specified: dump all the providers
15107      *  - a flattened component name that matched an existing provider was specified as the
15108      *    first arg: dump that one provider
15109      *  - the first arg isn't the flattened component name of an existing provider:
15110      *    dump all providers whose component contains the first arg as a substring
15111      */
15112     protected boolean dumpProvider(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15113             int opti, boolean dumpAll) {
15114         return mProviderMap.dumpProvider(fd, pw, name, args, opti, dumpAll);
15115     }
15116
15117     static class ItemMatcher {
15118         ArrayList<ComponentName> components;
15119         ArrayList<String> strings;
15120         ArrayList<Integer> objects;
15121         boolean all;
15122
15123         ItemMatcher() {
15124             all = true;
15125         }
15126
15127         void build(String name) {
15128             ComponentName componentName = ComponentName.unflattenFromString(name);
15129             if (componentName != null) {
15130                 if (components == null) {
15131                     components = new ArrayList<ComponentName>();
15132                 }
15133                 components.add(componentName);
15134                 all = false;
15135             } else {
15136                 int objectId = 0;
15137                 // Not a '/' separated full component name; maybe an object ID?
15138                 try {
15139                     objectId = Integer.parseInt(name, 16);
15140                     if (objects == null) {
15141                         objects = new ArrayList<Integer>();
15142                     }
15143                     objects.add(objectId);
15144                     all = false;
15145                 } catch (RuntimeException e) {
15146                     // Not an integer; just do string match.
15147                     if (strings == null) {
15148                         strings = new ArrayList<String>();
15149                     }
15150                     strings.add(name);
15151                     all = false;
15152                 }
15153             }
15154         }
15155
15156         int build(String[] args, int opti) {
15157             for (; opti<args.length; opti++) {
15158                 String name = args[opti];
15159                 if ("--".equals(name)) {
15160                     return opti+1;
15161                 }
15162                 build(name);
15163             }
15164             return opti;
15165         }
15166
15167         boolean match(Object object, ComponentName comp) {
15168             if (all) {
15169                 return true;
15170             }
15171             if (components != null) {
15172                 for (int i=0; i<components.size(); i++) {
15173                     if (components.get(i).equals(comp)) {
15174                         return true;
15175                     }
15176                 }
15177             }
15178             if (objects != null) {
15179                 for (int i=0; i<objects.size(); i++) {
15180                     if (System.identityHashCode(object) == objects.get(i)) {
15181                         return true;
15182                     }
15183                 }
15184             }
15185             if (strings != null) {
15186                 String flat = comp.flattenToString();
15187                 for (int i=0; i<strings.size(); i++) {
15188                     if (flat.contains(strings.get(i))) {
15189                         return true;
15190                     }
15191                 }
15192             }
15193             return false;
15194         }
15195     }
15196
15197     /**
15198      * There are three things that cmd can be:
15199      *  - a flattened component name that matches an existing activity
15200      *  - the cmd arg isn't the flattened component name of an existing activity:
15201      *    dump all activity whose component contains the cmd as a substring
15202      *  - A hex number of the ActivityRecord object instance.
15203      */
15204     protected boolean dumpActivity(FileDescriptor fd, PrintWriter pw, String name, String[] args,
15205             int opti, boolean dumpAll) {
15206         ArrayList<ActivityRecord> activities;
15207
15208         synchronized (this) {
15209             activities = mStackSupervisor.getDumpActivitiesLocked(name);
15210         }
15211
15212         if (activities.size() <= 0) {
15213             return false;
15214         }
15215
15216         String[] newArgs = new String[args.length - opti];
15217         System.arraycopy(args, opti, newArgs, 0, args.length - opti);
15218
15219         TaskRecord lastTask = null;
15220         boolean needSep = false;
15221         for (int i=activities.size()-1; i>=0; i--) {
15222             ActivityRecord r = activities.get(i);
15223             if (needSep) {
15224                 pw.println();
15225             }
15226             needSep = true;
15227             synchronized (this) {
15228                 if (lastTask != r.task) {
15229                     lastTask = r.task;
15230                     pw.print("TASK "); pw.print(lastTask.affinity);
15231                             pw.print(" id="); pw.println(lastTask.taskId);
15232                     if (dumpAll) {
15233                         lastTask.dump(pw, "  ");
15234                     }
15235                 }
15236             }
15237             dumpActivity("  ", fd, pw, activities.get(i), newArgs, dumpAll);
15238         }
15239         return true;
15240     }
15241
15242     /**
15243      * Invokes IApplicationThread.dumpActivity() on the thread of the specified activity if
15244      * there is a thread associated with the activity.
15245      */
15246     private void dumpActivity(String prefix, FileDescriptor fd, PrintWriter pw,
15247             final ActivityRecord r, String[] args, boolean dumpAll) {
15248         String innerPrefix = prefix + "  ";
15249         synchronized (this) {
15250             pw.print(prefix); pw.print("ACTIVITY "); pw.print(r.shortComponentName);
15251                     pw.print(" "); pw.print(Integer.toHexString(System.identityHashCode(r)));
15252                     pw.print(" pid=");
15253                     if (r.app != null) pw.println(r.app.pid);
15254                     else pw.println("(not running)");
15255             if (dumpAll) {
15256                 r.dump(pw, innerPrefix);
15257             }
15258         }
15259         if (r.app != null && r.app.thread != null) {
15260             // flush anything that is already in the PrintWriter since the thread is going
15261             // to write to the file descriptor directly
15262             pw.flush();
15263             try {
15264                 TransferPipe tp = new TransferPipe();
15265                 try {
15266                     r.app.thread.dumpActivity(tp.getWriteFd().getFileDescriptor(),
15267                             r.appToken, innerPrefix, args);
15268                     tp.go(fd);
15269                 } finally {
15270                     tp.kill();
15271                 }
15272             } catch (IOException e) {
15273                 pw.println(innerPrefix + "Failure while dumping the activity: " + e);
15274             } catch (RemoteException e) {
15275                 pw.println(innerPrefix + "Got a RemoteException while dumping the activity");
15276             }
15277         }
15278     }
15279
15280     void dumpBroadcastsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15281             int opti, boolean dumpAll, String dumpPackage) {
15282         boolean needSep = false;
15283         boolean onlyHistory = false;
15284         boolean printedAnything = false;
15285
15286         if ("history".equals(dumpPackage)) {
15287             if (opti < args.length && "-s".equals(args[opti])) {
15288                 dumpAll = false;
15289             }
15290             onlyHistory = true;
15291             dumpPackage = null;
15292         }
15293
15294         pw.println("ACTIVITY MANAGER BROADCAST STATE (dumpsys activity broadcasts)");
15295         if (!onlyHistory && dumpAll) {
15296             if (mRegisteredReceivers.size() > 0) {
15297                 boolean printed = false;
15298                 Iterator it = mRegisteredReceivers.values().iterator();
15299                 while (it.hasNext()) {
15300                     ReceiverList r = (ReceiverList)it.next();
15301                     if (dumpPackage != null && (r.app == null ||
15302                             !dumpPackage.equals(r.app.info.packageName))) {
15303                         continue;
15304                     }
15305                     if (!printed) {
15306                         pw.println("  Registered Receivers:");
15307                         needSep = true;
15308                         printed = true;
15309                         printedAnything = true;
15310                     }
15311                     pw.print("  * "); pw.println(r);
15312                     r.dump(pw, "    ");
15313                 }
15314             }
15315
15316             if (mReceiverResolver.dump(pw, needSep ?
15317                     "\n  Receiver Resolver Table:" : "  Receiver Resolver Table:",
15318                     "    ", dumpPackage, false, false)) {
15319                 needSep = true;
15320                 printedAnything = true;
15321             }
15322         }
15323
15324         for (BroadcastQueue q : mBroadcastQueues) {
15325             needSep = q.dumpLocked(fd, pw, args, opti, dumpAll, dumpPackage, needSep);
15326             printedAnything |= needSep;
15327         }
15328
15329         needSep = true;
15330
15331         if (!onlyHistory && mStickyBroadcasts != null && dumpPackage == null) {
15332             for (int user=0; user<mStickyBroadcasts.size(); user++) {
15333                 if (needSep) {
15334                     pw.println();
15335                 }
15336                 needSep = true;
15337                 printedAnything = true;
15338                 pw.print("  Sticky broadcasts for user ");
15339                         pw.print(mStickyBroadcasts.keyAt(user)); pw.println(":");
15340                 StringBuilder sb = new StringBuilder(128);
15341                 for (Map.Entry<String, ArrayList<Intent>> ent
15342                         : mStickyBroadcasts.valueAt(user).entrySet()) {
15343                     pw.print("  * Sticky action "); pw.print(ent.getKey());
15344                     if (dumpAll) {
15345                         pw.println(":");
15346                         ArrayList<Intent> intents = ent.getValue();
15347                         final int N = intents.size();
15348                         for (int i=0; i<N; i++) {
15349                             sb.setLength(0);
15350                             sb.append("    Intent: ");
15351                             intents.get(i).toShortString(sb, false, true, false, false);
15352                             pw.println(sb.toString());
15353                             Bundle bundle = intents.get(i).getExtras();
15354                             if (bundle != null) {
15355                                 pw.print("      ");
15356                                 pw.println(bundle.toString());
15357                             }
15358                         }
15359                     } else {
15360                         pw.println("");
15361                     }
15362                 }
15363             }
15364         }
15365
15366         if (!onlyHistory && dumpAll) {
15367             pw.println();
15368             for (BroadcastQueue queue : mBroadcastQueues) {
15369                 pw.println("  mBroadcastsScheduled [" + queue.mQueueName + "]="
15370                         + queue.mBroadcastsScheduled);
15371             }
15372             pw.println("  mHandler:");
15373             mHandler.dump(new PrintWriterPrinter(pw), "    ");
15374             needSep = true;
15375             printedAnything = true;
15376         }
15377
15378         if (!printedAnything) {
15379             pw.println("  (nothing)");
15380         }
15381     }
15382
15383     void dumpBroadcastStatsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15384             int opti, boolean dumpAll, String dumpPackage) {
15385         if (mCurBroadcastStats == null) {
15386             return;
15387         }
15388
15389         pw.println("ACTIVITY MANAGER BROADCAST STATS STATE (dumpsys activity broadcast-stats)");
15390         final long now = SystemClock.elapsedRealtime();
15391         if (mLastBroadcastStats != null) {
15392             pw.print("  Last stats (from ");
15393             TimeUtils.formatDuration(mLastBroadcastStats.mStartRealtime, now, pw);
15394             pw.print(" to ");
15395             TimeUtils.formatDuration(mLastBroadcastStats.mEndRealtime, now, pw);
15396             pw.print(", ");
15397             TimeUtils.formatDuration(mLastBroadcastStats.mEndUptime
15398                     - mLastBroadcastStats.mStartUptime, pw);
15399             pw.println(" uptime):");
15400             if (!mLastBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15401                 pw.println("    (nothing)");
15402             }
15403             pw.println();
15404         }
15405         pw.print("  Current stats (from ");
15406         TimeUtils.formatDuration(mCurBroadcastStats.mStartRealtime, now, pw);
15407         pw.print(" to now, ");
15408         TimeUtils.formatDuration(SystemClock.uptimeMillis()
15409                 - mCurBroadcastStats.mStartUptime, pw);
15410         pw.println(" uptime):");
15411         if (!mCurBroadcastStats.dumpStats(pw, "    ", dumpPackage)) {
15412             pw.println("    (nothing)");
15413         }
15414     }
15415
15416     void dumpBroadcastStatsCheckinLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15417             int opti, boolean fullCheckin, String dumpPackage) {
15418         if (mCurBroadcastStats == null) {
15419             return;
15420         }
15421
15422         if (mLastBroadcastStats != null) {
15423             mLastBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15424             if (fullCheckin) {
15425                 mLastBroadcastStats = null;
15426                 return;
15427             }
15428         }
15429         mCurBroadcastStats.dumpCheckinStats(pw, dumpPackage);
15430         if (fullCheckin) {
15431             mCurBroadcastStats = null;
15432         }
15433     }
15434
15435     void dumpProvidersLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15436             int opti, boolean dumpAll, String dumpPackage) {
15437         boolean needSep;
15438         boolean printedAnything = false;
15439
15440         ItemMatcher matcher = new ItemMatcher();
15441         matcher.build(args, opti);
15442
15443         pw.println("ACTIVITY MANAGER CONTENT PROVIDERS (dumpsys activity providers)");
15444
15445         needSep = mProviderMap.dumpProvidersLocked(pw, dumpAll, dumpPackage);
15446         printedAnything |= needSep;
15447
15448         if (mLaunchingProviders.size() > 0) {
15449             boolean printed = false;
15450             for (int i=mLaunchingProviders.size()-1; i>=0; i--) {
15451                 ContentProviderRecord r = mLaunchingProviders.get(i);
15452                 if (dumpPackage != null && !dumpPackage.equals(r.name.getPackageName())) {
15453                     continue;
15454                 }
15455                 if (!printed) {
15456                     if (needSep) pw.println();
15457                     needSep = true;
15458                     pw.println("  Launching content providers:");
15459                     printed = true;
15460                     printedAnything = true;
15461                 }
15462                 pw.print("  Launching #"); pw.print(i); pw.print(": ");
15463                         pw.println(r);
15464             }
15465         }
15466
15467         if (!printedAnything) {
15468             pw.println("  (nothing)");
15469         }
15470     }
15471
15472     void dumpPermissionsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15473             int opti, boolean dumpAll, String dumpPackage) {
15474         boolean needSep = false;
15475         boolean printedAnything = false;
15476
15477         pw.println("ACTIVITY MANAGER URI PERMISSIONS (dumpsys activity permissions)");
15478
15479         if (mGrantedUriPermissions.size() > 0) {
15480             boolean printed = false;
15481             int dumpUid = -2;
15482             if (dumpPackage != null) {
15483                 try {
15484                     dumpUid = mContext.getPackageManager().getPackageUidAsUser(dumpPackage,
15485                             MATCH_UNINSTALLED_PACKAGES, 0);
15486                 } catch (NameNotFoundException e) {
15487                     dumpUid = -1;
15488                 }
15489             }
15490             for (int i=0; i<mGrantedUriPermissions.size(); i++) {
15491                 int uid = mGrantedUriPermissions.keyAt(i);
15492                 if (dumpUid >= -1 && UserHandle.getAppId(uid) != dumpUid) {
15493                     continue;
15494                 }
15495                 final ArrayMap<GrantUri, UriPermission> perms = mGrantedUriPermissions.valueAt(i);
15496                 if (!printed) {
15497                     if (needSep) pw.println();
15498                     needSep = true;
15499                     pw.println("  Granted Uri Permissions:");
15500                     printed = true;
15501                     printedAnything = true;
15502                 }
15503                 pw.print("  * UID "); pw.print(uid); pw.println(" holds:");
15504                 for (UriPermission perm : perms.values()) {
15505                     pw.print("    "); pw.println(perm);
15506                     if (dumpAll) {
15507                         perm.dump(pw, "      ");
15508                     }
15509                 }
15510             }
15511         }
15512
15513         if (!printedAnything) {
15514             pw.println("  (nothing)");
15515         }
15516     }
15517
15518     void dumpPendingIntentsLocked(FileDescriptor fd, PrintWriter pw, String[] args,
15519             int opti, boolean dumpAll, String dumpPackage) {
15520         boolean printed = false;
15521
15522         pw.println("ACTIVITY MANAGER PENDING INTENTS (dumpsys activity intents)");
15523
15524         if (mIntentSenderRecords.size() > 0) {
15525             Iterator<WeakReference<PendingIntentRecord>> it
15526                     = mIntentSenderRecords.values().iterator();
15527             while (it.hasNext()) {
15528                 WeakReference<PendingIntentRecord> ref = it.next();
15529                 PendingIntentRecord rec = ref != null ? ref.get(): null;
15530                 if (dumpPackage != null && (rec == null
15531                         || !dumpPackage.equals(rec.key.packageName))) {
15532                     continue;
15533                 }
15534                 printed = true;
15535                 if (rec != null) {
15536                     pw.print("  * "); pw.println(rec);
15537                     if (dumpAll) {
15538                         rec.dump(pw, "    ");
15539                     }
15540                 } else {
15541                     pw.print("  * "); pw.println(ref);
15542                 }
15543             }
15544         }
15545
15546         if (!printed) {
15547             pw.println("  (nothing)");
15548         }
15549     }
15550
15551     private static final int dumpProcessList(PrintWriter pw,
15552             ActivityManagerService service, List list,
15553             String prefix, String normalLabel, String persistentLabel,
15554             String dumpPackage) {
15555         int numPers = 0;
15556         final int N = list.size()-1;
15557         for (int i=N; i>=0; i--) {
15558             ProcessRecord r = (ProcessRecord)list.get(i);
15559             if (dumpPackage != null && !dumpPackage.equals(r.info.packageName)) {
15560                 continue;
15561             }
15562             pw.println(String.format("%s%s #%2d: %s",
15563                     prefix, (r.persistent ? persistentLabel : normalLabel),
15564                     i, r.toString()));
15565             if (r.persistent) {
15566                 numPers++;
15567             }
15568         }
15569         return numPers;
15570     }
15571
15572     private static final boolean dumpProcessOomList(PrintWriter pw,
15573             ActivityManagerService service, List<ProcessRecord> origList,
15574             String prefix, String normalLabel, String persistentLabel,
15575             boolean inclDetails, String dumpPackage) {
15576
15577         ArrayList<Pair<ProcessRecord, Integer>> list
15578                 = new ArrayList<Pair<ProcessRecord, Integer>>(origList.size());
15579         for (int i=0; i<origList.size(); i++) {
15580             ProcessRecord r = origList.get(i);
15581             if (dumpPackage != null && !r.pkgList.containsKey(dumpPackage)) {
15582                 continue;
15583             }
15584             list.add(new Pair<ProcessRecord, Integer>(origList.get(i), i));
15585         }
15586
15587         if (list.size() <= 0) {
15588             return false;
15589         }
15590
15591         Comparator<Pair<ProcessRecord, Integer>> comparator
15592                 = new Comparator<Pair<ProcessRecord, Integer>>() {
15593             @Override
15594             public int compare(Pair<ProcessRecord, Integer> object1,
15595                     Pair<ProcessRecord, Integer> object2) {
15596                 if (object1.first.setAdj != object2.first.setAdj) {
15597                     return object1.first.setAdj > object2.first.setAdj ? -1 : 1;
15598                 }
15599                 if (object1.first.setProcState != object2.first.setProcState) {
15600                     return object1.first.setProcState > object2.first.setProcState ? -1 : 1;
15601                 }
15602                 if (object1.second.intValue() != object2.second.intValue()) {
15603                     return object1.second.intValue() > object2.second.intValue() ? -1 : 1;
15604                 }
15605                 return 0;
15606             }
15607         };
15608
15609         Collections.sort(list, comparator);
15610
15611         final long curRealtime = SystemClock.elapsedRealtime();
15612         final long realtimeSince = curRealtime - service.mLastPowerCheckRealtime;
15613         final long curUptime = SystemClock.uptimeMillis();
15614         final long uptimeSince = curUptime - service.mLastPowerCheckUptime;
15615
15616         for (int i=list.size()-1; i>=0; i--) {
15617             ProcessRecord r = list.get(i).first;
15618             String oomAdj = ProcessList.makeOomAdjString(r.setAdj);
15619             char schedGroup;
15620             switch (r.setSchedGroup) {
15621                 case ProcessList.SCHED_GROUP_BACKGROUND:
15622                     schedGroup = 'B';
15623                     break;
15624                 case ProcessList.SCHED_GROUP_DEFAULT:
15625                     schedGroup = 'F';
15626                     break;
15627                 case ProcessList.SCHED_GROUP_TOP_APP:
15628                     schedGroup = 'T';
15629                     break;
15630                 default:
15631                     schedGroup = '?';
15632                     break;
15633             }
15634             char foreground;
15635             if (r.foregroundActivities) {
15636                 foreground = 'A';
15637             } else if (r.foregroundServices) {
15638                 foreground = 'S';
15639             } else {
15640                 foreground = ' ';
15641             }
15642             String procState = ProcessList.makeProcStateString(r.curProcState);
15643             pw.print(prefix);
15644             pw.print(r.persistent ? persistentLabel : normalLabel);
15645             pw.print(" #");
15646             int num = (origList.size()-1)-list.get(i).second;
15647             if (num < 10) pw.print(' ');
15648             pw.print(num);
15649             pw.print(": ");
15650             pw.print(oomAdj);
15651             pw.print(' ');
15652             pw.print(schedGroup);
15653             pw.print('/');
15654             pw.print(foreground);
15655             pw.print('/');
15656             pw.print(procState);
15657             pw.print(" trm:");
15658             if (r.trimMemoryLevel < 10) pw.print(' ');
15659             pw.print(r.trimMemoryLevel);
15660             pw.print(' ');
15661             pw.print(r.toShortString());
15662             pw.print(" (");
15663             pw.print(r.adjType);
15664             pw.println(')');
15665             if (r.adjSource != null || r.adjTarget != null) {
15666                 pw.print(prefix);
15667                 pw.print("    ");
15668                 if (r.adjTarget instanceof ComponentName) {
15669                     pw.print(((ComponentName)r.adjTarget).flattenToShortString());
15670                 } else if (r.adjTarget != null) {
15671                     pw.print(r.adjTarget.toString());
15672                 } else {
15673                     pw.print("{null}");
15674                 }
15675                 pw.print("<=");
15676                 if (r.adjSource instanceof ProcessRecord) {
15677                     pw.print("Proc{");
15678                     pw.print(((ProcessRecord)r.adjSource).toShortString());
15679                     pw.println("}");
15680                 } else if (r.adjSource != null) {
15681                     pw.println(r.adjSource.toString());
15682                 } else {
15683                     pw.println("{null}");
15684                 }
15685             }
15686             if (inclDetails) {
15687                 pw.print(prefix);
15688                 pw.print("    ");
15689                 pw.print("oom: max="); pw.print(r.maxAdj);
15690                 pw.print(" curRaw="); pw.print(r.curRawAdj);
15691                 pw.print(" setRaw="); pw.print(r.setRawAdj);
15692                 pw.print(" cur="); pw.print(r.curAdj);
15693                 pw.print(" set="); pw.println(r.setAdj);
15694                 pw.print(prefix);
15695                 pw.print("    ");
15696                 pw.print("state: cur="); pw.print(ProcessList.makeProcStateString(r.curProcState));
15697                 pw.print(" set="); pw.print(ProcessList.makeProcStateString(r.setProcState));
15698                 pw.print(" lastPss="); DebugUtils.printSizeValue(pw, r.lastPss*1024);
15699                 pw.print(" lastSwapPss="); DebugUtils.printSizeValue(pw, r.lastSwapPss*1024);
15700                 pw.print(" lastCachedPss="); DebugUtils.printSizeValue(pw, r.lastCachedPss*1024);
15701                 pw.println();
15702                 pw.print(prefix);
15703                 pw.print("    ");
15704                 pw.print("cached="); pw.print(r.cached);
15705                 pw.print(" empty="); pw.print(r.empty);
15706                 pw.print(" hasAboveClient="); pw.println(r.hasAboveClient);
15707
15708                 if (r.setProcState >= ActivityManager.PROCESS_STATE_SERVICE) {
15709                     if (r.lastWakeTime != 0) {
15710                         long wtime;
15711                         BatteryStatsImpl stats = service.mBatteryStatsService.getActiveStatistics();
15712                         synchronized (stats) {
15713                             wtime = stats.getProcessWakeTime(r.info.uid,
15714                                     r.pid, curRealtime);
15715                         }
15716                         long timeUsed = wtime - r.lastWakeTime;
15717                         pw.print(prefix);
15718                         pw.print("    ");
15719                         pw.print("keep awake over ");
15720                         TimeUtils.formatDuration(realtimeSince, pw);
15721                         pw.print(" used ");
15722                         TimeUtils.formatDuration(timeUsed, pw);
15723                         pw.print(" (");
15724                         pw.print((timeUsed*100)/realtimeSince);
15725                         pw.println("%)");
15726                     }
15727                     if (r.lastCpuTime != 0) {
15728                         long timeUsed = r.curCpuTime - r.lastCpuTime;
15729                         pw.print(prefix);
15730                         pw.print("    ");
15731                         pw.print("run cpu over ");
15732                         TimeUtils.formatDuration(uptimeSince, pw);
15733                         pw.print(" used ");
15734                         TimeUtils.formatDuration(timeUsed, pw);
15735                         pw.print(" (");
15736                         pw.print((timeUsed*100)/uptimeSince);
15737                         pw.println("%)");
15738                     }
15739                 }
15740             }
15741         }
15742         return true;
15743     }
15744
15745     ArrayList<ProcessRecord> collectProcesses(PrintWriter pw, int start, boolean allPkgs,
15746             String[] args) {
15747         ArrayList<ProcessRecord> procs;
15748         synchronized (this) {
15749             if (args != null && args.length > start
15750                     && args[start].charAt(0) != '-') {
15751                 procs = new ArrayList<ProcessRecord>();
15752                 int pid = -1;
15753                 try {
15754                     pid = Integer.parseInt(args[start]);
15755                 } catch (NumberFormatException e) {
15756                 }
15757                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
15758                     ProcessRecord proc = mLruProcesses.get(i);
15759                     if (proc.pid == pid) {
15760                         procs.add(proc);
15761                     } else if (allPkgs && proc.pkgList != null
15762                             && proc.pkgList.containsKey(args[start])) {
15763                         procs.add(proc);
15764                     } else if (proc.processName.equals(args[start])) {
15765                         procs.add(proc);
15766                     }
15767                 }
15768                 if (procs.size() <= 0) {
15769                     return null;
15770                 }
15771             } else {
15772                 procs = new ArrayList<ProcessRecord>(mLruProcesses);
15773             }
15774         }
15775         return procs;
15776     }
15777
15778     final void dumpGraphicsHardwareUsage(FileDescriptor fd,
15779             PrintWriter pw, String[] args) {
15780         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15781         if (procs == null) {
15782             pw.println("No process found for: " + args[0]);
15783             return;
15784         }
15785
15786         long uptime = SystemClock.uptimeMillis();
15787         long realtime = SystemClock.elapsedRealtime();
15788         pw.println("Applications Graphics Acceleration Info:");
15789         pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15790
15791         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15792             ProcessRecord r = procs.get(i);
15793             if (r.thread != null) {
15794                 pw.println("\n** Graphics info for pid " + r.pid + " [" + r.processName + "] **");
15795                 pw.flush();
15796                 try {
15797                     TransferPipe tp = new TransferPipe();
15798                     try {
15799                         r.thread.dumpGfxInfo(tp.getWriteFd().getFileDescriptor(), args);
15800                         tp.go(fd);
15801                     } finally {
15802                         tp.kill();
15803                     }
15804                 } catch (IOException e) {
15805                     pw.println("Failure while dumping the app: " + r);
15806                     pw.flush();
15807                 } catch (RemoteException e) {
15808                     pw.println("Got a RemoteException while dumping the app " + r);
15809                     pw.flush();
15810                 }
15811             }
15812         }
15813     }
15814
15815     final void dumpDbInfo(FileDescriptor fd, PrintWriter pw, String[] args) {
15816         ArrayList<ProcessRecord> procs = collectProcesses(pw, 0, false, args);
15817         if (procs == null) {
15818             pw.println("No process found for: " + args[0]);
15819             return;
15820         }
15821
15822         pw.println("Applications Database Info:");
15823
15824         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
15825             ProcessRecord r = procs.get(i);
15826             if (r.thread != null) {
15827                 pw.println("\n** Database info for pid " + r.pid + " [" + r.processName + "] **");
15828                 pw.flush();
15829                 try {
15830                     TransferPipe tp = new TransferPipe();
15831                     try {
15832                         r.thread.dumpDbInfo(tp.getWriteFd().getFileDescriptor(), args);
15833                         tp.go(fd);
15834                     } finally {
15835                         tp.kill();
15836                     }
15837                 } catch (IOException e) {
15838                     pw.println("Failure while dumping the app: " + r);
15839                     pw.flush();
15840                 } catch (RemoteException e) {
15841                     pw.println("Got a RemoteException while dumping the app " + r);
15842                     pw.flush();
15843                 }
15844             }
15845         }
15846     }
15847
15848     final static class MemItem {
15849         final boolean isProc;
15850         final String label;
15851         final String shortLabel;
15852         final long pss;
15853         final long swapPss;
15854         final int id;
15855         final boolean hasActivities;
15856         ArrayList<MemItem> subitems;
15857
15858         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id,
15859                 boolean _hasActivities) {
15860             isProc = true;
15861             label = _label;
15862             shortLabel = _shortLabel;
15863             pss = _pss;
15864             swapPss = _swapPss;
15865             id = _id;
15866             hasActivities = _hasActivities;
15867         }
15868
15869         public MemItem(String _label, String _shortLabel, long _pss, long _swapPss, int _id) {
15870             isProc = false;
15871             label = _label;
15872             shortLabel = _shortLabel;
15873             pss = _pss;
15874             swapPss = _swapPss;
15875             id = _id;
15876             hasActivities = false;
15877         }
15878     }
15879
15880     static final void dumpMemItems(PrintWriter pw, String prefix, String tag,
15881             ArrayList<MemItem> items, boolean sort, boolean isCompact, boolean dumpSwapPss) {
15882         if (sort && !isCompact) {
15883             Collections.sort(items, new Comparator<MemItem>() {
15884                 @Override
15885                 public int compare(MemItem lhs, MemItem rhs) {
15886                     if (lhs.pss < rhs.pss) {
15887                         return 1;
15888                     } else if (lhs.pss > rhs.pss) {
15889                         return -1;
15890                     }
15891                     return 0;
15892                 }
15893             });
15894         }
15895
15896         for (int i=0; i<items.size(); i++) {
15897             MemItem mi = items.get(i);
15898             if (!isCompact) {
15899                 if (dumpSwapPss) {
15900                     pw.printf("%s%s: %-60s (%s in swap)\n", prefix, stringifyKBSize(mi.pss),
15901                             mi.label, stringifyKBSize(mi.swapPss));
15902                 } else {
15903                     pw.printf("%s%s: %s\n", prefix, stringifyKBSize(mi.pss), mi.label);
15904                 }
15905             } else if (mi.isProc) {
15906                 pw.print("proc,"); pw.print(tag); pw.print(","); pw.print(mi.shortLabel);
15907                 pw.print(","); pw.print(mi.id); pw.print(","); pw.print(mi.pss); pw.print(",");
15908                 pw.print(dumpSwapPss ? mi.swapPss : "N/A");
15909                 pw.println(mi.hasActivities ? ",a" : ",e");
15910             } else {
15911                 pw.print(tag); pw.print(","); pw.print(mi.shortLabel); pw.print(",");
15912                 pw.print(mi.pss); pw.print(","); pw.println(dumpSwapPss ? mi.swapPss : "N/A");
15913             }
15914             if (mi.subitems != null) {
15915                 dumpMemItems(pw, prefix + "    ", mi.shortLabel, mi.subitems,
15916                         true, isCompact, dumpSwapPss);
15917             }
15918         }
15919     }
15920
15921     // These are in KB.
15922     static final long[] DUMP_MEM_BUCKETS = new long[] {
15923         5*1024, 7*1024, 10*1024, 15*1024, 20*1024, 30*1024, 40*1024, 80*1024,
15924         120*1024, 160*1024, 200*1024,
15925         250*1024, 300*1024, 350*1024, 400*1024, 500*1024, 600*1024, 800*1024,
15926         1*1024*1024, 2*1024*1024, 5*1024*1024, 10*1024*1024, 20*1024*1024
15927     };
15928
15929     static final void appendMemBucket(StringBuilder out, long memKB, String label,
15930             boolean stackLike) {
15931         int start = label.lastIndexOf('.');
15932         if (start >= 0) start++;
15933         else start = 0;
15934         int end = label.length();
15935         for (int i=0; i<DUMP_MEM_BUCKETS.length; i++) {
15936             if (DUMP_MEM_BUCKETS[i] >= memKB) {
15937                 long bucket = DUMP_MEM_BUCKETS[i]/1024;
15938                 out.append(bucket);
15939                 out.append(stackLike ? "MB." : "MB ");
15940                 out.append(label, start, end);
15941                 return;
15942             }
15943         }
15944         out.append(memKB/1024);
15945         out.append(stackLike ? "MB." : "MB ");
15946         out.append(label, start, end);
15947     }
15948
15949     static final int[] DUMP_MEM_OOM_ADJ = new int[] {
15950             ProcessList.NATIVE_ADJ,
15951             ProcessList.SYSTEM_ADJ, ProcessList.PERSISTENT_PROC_ADJ,
15952             ProcessList.PERSISTENT_SERVICE_ADJ, ProcessList.FOREGROUND_APP_ADJ,
15953             ProcessList.VISIBLE_APP_ADJ, ProcessList.PERCEPTIBLE_APP_ADJ,
15954             ProcessList.BACKUP_APP_ADJ, ProcessList.HEAVY_WEIGHT_APP_ADJ,
15955             ProcessList.SERVICE_ADJ, ProcessList.HOME_APP_ADJ,
15956             ProcessList.PREVIOUS_APP_ADJ, ProcessList.SERVICE_B_ADJ, ProcessList.CACHED_APP_MIN_ADJ
15957     };
15958     static final String[] DUMP_MEM_OOM_LABEL = new String[] {
15959             "Native",
15960             "System", "Persistent", "Persistent Service", "Foreground",
15961             "Visible", "Perceptible",
15962             "Heavy Weight", "Backup",
15963             "A Services", "Home",
15964             "Previous", "B Services", "Cached"
15965     };
15966     static final String[] DUMP_MEM_OOM_COMPACT_LABEL = new String[] {
15967             "native",
15968             "sys", "pers", "persvc", "fore",
15969             "vis", "percept",
15970             "heavy", "backup",
15971             "servicea", "home",
15972             "prev", "serviceb", "cached"
15973     };
15974
15975     private final void dumpApplicationMemoryUsageHeader(PrintWriter pw, long uptime,
15976             long realtime, boolean isCheckinRequest, boolean isCompact) {
15977         if (isCompact) {
15978             pw.print("version,"); pw.println(MEMINFO_COMPACT_VERSION);
15979         }
15980         if (isCheckinRequest || isCompact) {
15981             // short checkin version
15982             pw.print("time,"); pw.print(uptime); pw.print(","); pw.println(realtime);
15983         } else {
15984             pw.println("Applications Memory Usage (in Kilobytes):");
15985             pw.println("Uptime: " + uptime + " Realtime: " + realtime);
15986         }
15987     }
15988
15989     private static final int KSM_SHARED = 0;
15990     private static final int KSM_SHARING = 1;
15991     private static final int KSM_UNSHARED = 2;
15992     private static final int KSM_VOLATILE = 3;
15993
15994     private final long[] getKsmInfo() {
15995         long[] longOut = new long[4];
15996         final int[] SINGLE_LONG_FORMAT = new int[] {
15997             Process.PROC_SPACE_TERM|Process.PROC_OUT_LONG
15998         };
15999         long[] longTmp = new long[1];
16000         Process.readProcFile("/sys/kernel/mm/ksm/pages_shared",
16001                 SINGLE_LONG_FORMAT, null, longTmp, null);
16002         longOut[KSM_SHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16003         longTmp[0] = 0;
16004         Process.readProcFile("/sys/kernel/mm/ksm/pages_sharing",
16005                 SINGLE_LONG_FORMAT, null, longTmp, null);
16006         longOut[KSM_SHARING] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16007         longTmp[0] = 0;
16008         Process.readProcFile("/sys/kernel/mm/ksm/pages_unshared",
16009                 SINGLE_LONG_FORMAT, null, longTmp, null);
16010         longOut[KSM_UNSHARED] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16011         longTmp[0] = 0;
16012         Process.readProcFile("/sys/kernel/mm/ksm/pages_volatile",
16013                 SINGLE_LONG_FORMAT, null, longTmp, null);
16014         longOut[KSM_VOLATILE] = longTmp[0] * ProcessList.PAGE_SIZE / 1024;
16015         return longOut;
16016     }
16017
16018     private static String stringifySize(long size, int order) {
16019         Locale locale = Locale.US;
16020         switch (order) {
16021             case 1:
16022                 return String.format(locale, "%,13d", size);
16023             case 1024:
16024                 return String.format(locale, "%,9dK", size / 1024);
16025             case 1024 * 1024:
16026                 return String.format(locale, "%,5dM", size / 1024 / 1024);
16027             case 1024 * 1024 * 1024:
16028                 return String.format(locale, "%,1dG", size / 1024 / 1024 / 1024);
16029             default:
16030                 throw new IllegalArgumentException("Invalid size order");
16031         }
16032     }
16033
16034     private static String stringifyKBSize(long size) {
16035         return stringifySize(size * 1024, 1024);
16036     }
16037
16038     // Update this version number in case you change the 'compact' format
16039     private static final int MEMINFO_COMPACT_VERSION = 1;
16040
16041     final void dumpApplicationMemoryUsage(FileDescriptor fd,
16042             PrintWriter pw, String prefix, String[] args, boolean brief, PrintWriter categoryPw) {
16043         boolean dumpDetails = false;
16044         boolean dumpFullDetails = false;
16045         boolean dumpDalvik = false;
16046         boolean dumpSummaryOnly = false;
16047         boolean dumpUnreachable = false;
16048         boolean oomOnly = false;
16049         boolean isCompact = false;
16050         boolean localOnly = false;
16051         boolean packages = false;
16052         boolean isCheckinRequest = false;
16053         boolean dumpSwapPss = false;
16054
16055         int opti = 0;
16056         while (opti < args.length) {
16057             String opt = args[opti];
16058             if (opt == null || opt.length() <= 0 || opt.charAt(0) != '-') {
16059                 break;
16060             }
16061             opti++;
16062             if ("-a".equals(opt)) {
16063                 dumpDetails = true;
16064                 dumpFullDetails = true;
16065                 dumpDalvik = true;
16066                 dumpSwapPss = true;
16067             } else if ("-d".equals(opt)) {
16068                 dumpDalvik = true;
16069             } else if ("-c".equals(opt)) {
16070                 isCompact = true;
16071             } else if ("-s".equals(opt)) {
16072                 dumpDetails = true;
16073                 dumpSummaryOnly = true;
16074             } else if ("-S".equals(opt)) {
16075                 dumpSwapPss = true;
16076             } else if ("--unreachable".equals(opt)) {
16077                 dumpUnreachable = true;
16078             } else if ("--oom".equals(opt)) {
16079                 oomOnly = true;
16080             } else if ("--local".equals(opt)) {
16081                 localOnly = true;
16082             } else if ("--package".equals(opt)) {
16083                 packages = true;
16084             } else if ("--checkin".equals(opt)) {
16085                 isCheckinRequest = true;
16086
16087             } else if ("-h".equals(opt)) {
16088                 pw.println("meminfo dump options: [-a] [-d] [-c] [-s] [--oom] [process]");
16089                 pw.println("  -a: include all available information for each process.");
16090                 pw.println("  -d: include dalvik details.");
16091                 pw.println("  -c: dump in a compact machine-parseable representation.");
16092                 pw.println("  -s: dump only summary of application memory usage.");
16093                 pw.println("  -S: dump also SwapPss.");
16094                 pw.println("  --oom: only show processes organized by oom adj.");
16095                 pw.println("  --local: only collect details locally, don't call process.");
16096                 pw.println("  --package: interpret process arg as package, dumping all");
16097                 pw.println("             processes that have loaded that package.");
16098                 pw.println("  --checkin: dump data for a checkin");
16099                 pw.println("If [process] is specified it can be the name or ");
16100                 pw.println("pid of a specific process to dump.");
16101                 return;
16102             } else {
16103                 pw.println("Unknown argument: " + opt + "; use -h for help");
16104             }
16105         }
16106
16107         long uptime = SystemClock.uptimeMillis();
16108         long realtime = SystemClock.elapsedRealtime();
16109         final long[] tmpLong = new long[1];
16110
16111         ArrayList<ProcessRecord> procs = collectProcesses(pw, opti, packages, args);
16112         if (procs == null) {
16113             // No Java processes.  Maybe they want to print a native process.
16114             if (args != null && args.length > opti
16115                     && args[opti].charAt(0) != '-') {
16116                 ArrayList<ProcessCpuTracker.Stats> nativeProcs
16117                         = new ArrayList<ProcessCpuTracker.Stats>();
16118                 updateCpuStatsNow();
16119                 int findPid = -1;
16120                 try {
16121                     findPid = Integer.parseInt(args[opti]);
16122                 } catch (NumberFormatException e) {
16123                 }
16124                 synchronized (mProcessCpuTracker) {
16125                     final int N = mProcessCpuTracker.countStats();
16126                     for (int i=0; i<N; i++) {
16127                         ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16128                         if (st.pid == findPid || (st.baseName != null
16129                                 && st.baseName.equals(args[opti]))) {
16130                             nativeProcs.add(st);
16131                         }
16132                     }
16133                 }
16134                 if (nativeProcs.size() > 0) {
16135                     dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest,
16136                             isCompact);
16137                     Debug.MemoryInfo mi = null;
16138                     for (int i = nativeProcs.size() - 1 ; i >= 0 ; i--) {
16139                         final ProcessCpuTracker.Stats r = nativeProcs.get(i);
16140                         final int pid = r.pid;
16141                         if (!isCheckinRequest && dumpDetails) {
16142                             pw.println("\n** MEMINFO in pid " + pid + " [" + r.baseName + "] **");
16143                         }
16144                         if (mi == null) {
16145                             mi = new Debug.MemoryInfo();
16146                         }
16147                         if (dumpDetails || (!brief && !oomOnly)) {
16148                             Debug.getMemoryInfo(pid, mi);
16149                         } else {
16150                             mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16151                             mi.dalvikPrivateDirty = (int)tmpLong[0];
16152                         }
16153                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16154                                 dumpDalvik, dumpSummaryOnly, pid, r.baseName, 0, 0, 0, 0, 0, 0);
16155                         if (isCheckinRequest) {
16156                             pw.println();
16157                         }
16158                     }
16159                     return;
16160                 }
16161             }
16162             pw.println("No process found for: " + args[opti]);
16163             return;
16164         }
16165
16166         if (!brief && !oomOnly && (procs.size() == 1 || isCheckinRequest || packages)) {
16167             dumpDetails = true;
16168         }
16169
16170         dumpApplicationMemoryUsageHeader(pw, uptime, realtime, isCheckinRequest, isCompact);
16171
16172         String[] innerArgs = new String[args.length-opti];
16173         System.arraycopy(args, opti, innerArgs, 0, args.length-opti);
16174
16175         ArrayList<MemItem> procMems = new ArrayList<MemItem>();
16176         final SparseArray<MemItem> procMemsMap = new SparseArray<MemItem>();
16177         long nativePss = 0;
16178         long nativeSwapPss = 0;
16179         long dalvikPss = 0;
16180         long dalvikSwapPss = 0;
16181         long[] dalvikSubitemPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16182                 EmptyArray.LONG;
16183         long[] dalvikSubitemSwapPss = dumpDalvik ? new long[Debug.MemoryInfo.NUM_DVK_STATS] :
16184                 EmptyArray.LONG;
16185         long otherPss = 0;
16186         long otherSwapPss = 0;
16187         long[] miscPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16188         long[] miscSwapPss = new long[Debug.MemoryInfo.NUM_OTHER_STATS];
16189
16190         long oomPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16191         long oomSwapPss[] = new long[DUMP_MEM_OOM_LABEL.length];
16192         ArrayList<MemItem>[] oomProcs = (ArrayList<MemItem>[])
16193                 new ArrayList[DUMP_MEM_OOM_LABEL.length];
16194
16195         long totalPss = 0;
16196         long totalSwapPss = 0;
16197         long cachedPss = 0;
16198         long cachedSwapPss = 0;
16199         boolean hasSwapPss = false;
16200
16201         Debug.MemoryInfo mi = null;
16202         for (int i = procs.size() - 1 ; i >= 0 ; i--) {
16203             final ProcessRecord r = procs.get(i);
16204             final IApplicationThread thread;
16205             final int pid;
16206             final int oomAdj;
16207             final boolean hasActivities;
16208             synchronized (this) {
16209                 thread = r.thread;
16210                 pid = r.pid;
16211                 oomAdj = r.getSetAdjWithServices();
16212                 hasActivities = r.activities.size() > 0;
16213             }
16214             if (thread != null) {
16215                 if (!isCheckinRequest && dumpDetails) {
16216                     pw.println("\n** MEMINFO in pid " + pid + " [" + r.processName + "] **");
16217                 }
16218                 if (mi == null) {
16219                     mi = new Debug.MemoryInfo();
16220                 }
16221                 if (dumpDetails || (!brief && !oomOnly)) {
16222                     Debug.getMemoryInfo(pid, mi);
16223                     hasSwapPss = mi.hasSwappedOutPss;
16224                 } else {
16225                     mi.dalvikPss = (int)Debug.getPss(pid, tmpLong, null);
16226                     mi.dalvikPrivateDirty = (int)tmpLong[0];
16227                 }
16228                 if (dumpDetails) {
16229                     if (localOnly) {
16230                         ActivityThread.dumpMemInfoTable(pw, mi, isCheckinRequest, dumpFullDetails,
16231                                 dumpDalvik, dumpSummaryOnly, pid, r.processName, 0, 0, 0, 0, 0, 0);
16232                         if (isCheckinRequest) {
16233                             pw.println();
16234                         }
16235                     } else {
16236                         try {
16237                             pw.flush();
16238                             thread.dumpMemInfo(fd, mi, isCheckinRequest, dumpFullDetails,
16239                                     dumpDalvik, dumpSummaryOnly, dumpUnreachable, innerArgs);
16240                         } catch (RemoteException e) {
16241                             if (!isCheckinRequest) {
16242                                 pw.println("Got RemoteException!");
16243                                 pw.flush();
16244                             }
16245                         }
16246                     }
16247                 }
16248
16249                 final long myTotalPss = mi.getTotalPss();
16250                 final long myTotalUss = mi.getTotalUss();
16251                 final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16252
16253                 synchronized (this) {
16254                     if (r.thread != null && oomAdj == r.getSetAdjWithServices()) {
16255                         // Record this for posterity if the process has been stable.
16256                         r.baseProcessTracker.addPss(myTotalPss, myTotalUss, true, r.pkgList);
16257                     }
16258                 }
16259
16260                 if (!isCheckinRequest && mi != null) {
16261                     totalPss += myTotalPss;
16262                     totalSwapPss += myTotalSwapPss;
16263                     MemItem pssItem = new MemItem(r.processName + " (pid " + pid +
16264                             (hasActivities ? " / activities)" : ")"), r.processName, myTotalPss,
16265                             myTotalSwapPss, pid, hasActivities);
16266                     procMems.add(pssItem);
16267                     procMemsMap.put(pid, pssItem);
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
16289                     if (oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16290                         cachedPss += myTotalPss;
16291                         cachedSwapPss += myTotalSwapPss;
16292                     }
16293
16294                     for (int oomIndex=0; oomIndex<oomPss.length; oomIndex++) {
16295                         if (oomIndex == (oomPss.length - 1)
16296                                 || (oomAdj >= DUMP_MEM_OOM_ADJ[oomIndex]
16297                                         && oomAdj < DUMP_MEM_OOM_ADJ[oomIndex + 1])) {
16298                             oomPss[oomIndex] += myTotalPss;
16299                             oomSwapPss[oomIndex] += myTotalSwapPss;
16300                             if (oomProcs[oomIndex] == null) {
16301                                 oomProcs[oomIndex] = new ArrayList<MemItem>();
16302                             }
16303                             oomProcs[oomIndex].add(pssItem);
16304                             break;
16305                         }
16306                     }
16307                 }
16308             }
16309         }
16310
16311         long nativeProcTotalPss = 0;
16312
16313         if (!isCheckinRequest && procs.size() > 1 && !packages) {
16314             // If we are showing aggregations, also look for native processes to
16315             // include so that our aggregations are more accurate.
16316             updateCpuStatsNow();
16317             mi = null;
16318             synchronized (mProcessCpuTracker) {
16319                 final int N = mProcessCpuTracker.countStats();
16320                 for (int i=0; i<N; i++) {
16321                     ProcessCpuTracker.Stats st = mProcessCpuTracker.getStats(i);
16322                     if (st.vsize > 0 && procMemsMap.indexOfKey(st.pid) < 0) {
16323                         if (mi == null) {
16324                             mi = new Debug.MemoryInfo();
16325                         }
16326                         if (!brief && !oomOnly) {
16327                             Debug.getMemoryInfo(st.pid, mi);
16328                         } else {
16329                             mi.nativePss = (int)Debug.getPss(st.pid, tmpLong, null);
16330                             mi.nativePrivateDirty = (int)tmpLong[0];
16331                         }
16332
16333                         final long myTotalPss = mi.getTotalPss();
16334                         final long myTotalSwapPss = mi.getTotalSwappedOutPss();
16335                         totalPss += myTotalPss;
16336                         nativeProcTotalPss += myTotalPss;
16337
16338                         MemItem pssItem = new MemItem(st.name + " (pid " + st.pid + ")",
16339                                 st.name, myTotalPss, mi.getSummaryTotalSwapPss(), st.pid, false);
16340                         procMems.add(pssItem);
16341
16342                         nativePss += mi.nativePss;
16343                         nativeSwapPss += mi.nativeSwappedOutPss;
16344                         dalvikPss += mi.dalvikPss;
16345                         dalvikSwapPss += mi.dalvikSwappedOutPss;
16346                         for (int j=0; j<dalvikSubitemPss.length; j++) {
16347                             dalvikSubitemPss[j] += mi.getOtherPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16348                             dalvikSubitemSwapPss[j] +=
16349                                     mi.getOtherSwappedOutPss(Debug.MemoryInfo.NUM_OTHER_STATS + j);
16350                         }
16351                         otherPss += mi.otherPss;
16352                         otherSwapPss += mi.otherSwappedOutPss;
16353                         for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16354                             long mem = mi.getOtherPss(j);
16355                             miscPss[j] += mem;
16356                             otherPss -= mem;
16357                             mem = mi.getOtherSwappedOutPss(j);
16358                             miscSwapPss[j] += mem;
16359                             otherSwapPss -= mem;
16360                         }
16361                         oomPss[0] += myTotalPss;
16362                         oomSwapPss[0] += myTotalSwapPss;
16363                         if (oomProcs[0] == null) {
16364                             oomProcs[0] = new ArrayList<MemItem>();
16365                         }
16366                         oomProcs[0].add(pssItem);
16367                     }
16368                 }
16369             }
16370
16371             ArrayList<MemItem> catMems = new ArrayList<MemItem>();
16372
16373             catMems.add(new MemItem("Native", "Native", nativePss, nativeSwapPss, -1));
16374             final MemItem dalvikItem =
16375                     new MemItem("Dalvik", "Dalvik", dalvikPss, dalvikSwapPss, -2);
16376             if (dalvikSubitemPss.length > 0) {
16377                 dalvikItem.subitems = new ArrayList<MemItem>();
16378                 for (int j=0; j<dalvikSubitemPss.length; j++) {
16379                     final String name = Debug.MemoryInfo.getOtherLabel(
16380                             Debug.MemoryInfo.NUM_OTHER_STATS + j);
16381                     dalvikItem.subitems.add(new MemItem(name, name, dalvikSubitemPss[j],
16382                                     dalvikSubitemSwapPss[j], j));
16383                 }
16384             }
16385             catMems.add(dalvikItem);
16386             catMems.add(new MemItem("Unknown", "Unknown", otherPss, otherSwapPss, -3));
16387             for (int j=0; j<Debug.MemoryInfo.NUM_OTHER_STATS; j++) {
16388                 String label = Debug.MemoryInfo.getOtherLabel(j);
16389                 catMems.add(new MemItem(label, label, miscPss[j], miscSwapPss[j], j));
16390             }
16391
16392             ArrayList<MemItem> oomMems = new ArrayList<MemItem>();
16393             for (int j=0; j<oomPss.length; j++) {
16394                 if (oomPss[j] != 0) {
16395                     String label = isCompact ? DUMP_MEM_OOM_COMPACT_LABEL[j]
16396                             : DUMP_MEM_OOM_LABEL[j];
16397                     MemItem item = new MemItem(label, label, oomPss[j], oomSwapPss[j],
16398                             DUMP_MEM_OOM_ADJ[j]);
16399                     item.subitems = oomProcs[j];
16400                     oomMems.add(item);
16401                 }
16402             }
16403
16404             dumpSwapPss = dumpSwapPss && hasSwapPss && totalSwapPss != 0;
16405             if (!brief && !oomOnly && !isCompact) {
16406                 pw.println();
16407                 pw.println("Total PSS by process:");
16408                 dumpMemItems(pw, "  ", "proc", procMems, true, isCompact, dumpSwapPss);
16409                 pw.println();
16410             }
16411             if (!isCompact) {
16412                 pw.println("Total PSS by OOM adjustment:");
16413             }
16414             dumpMemItems(pw, "  ", "oom", oomMems, false, isCompact, dumpSwapPss);
16415             if (!brief && !oomOnly) {
16416                 PrintWriter out = categoryPw != null ? categoryPw : pw;
16417                 if (!isCompact) {
16418                     out.println();
16419                     out.println("Total PSS by category:");
16420                 }
16421                 dumpMemItems(out, "  ", "cat", catMems, true, isCompact, dumpSwapPss);
16422             }
16423             if (!isCompact) {
16424                 pw.println();
16425             }
16426             MemInfoReader memInfo = new MemInfoReader();
16427             memInfo.readMemInfo();
16428             if (nativeProcTotalPss > 0) {
16429                 synchronized (this) {
16430                     final long cachedKb = memInfo.getCachedSizeKb();
16431                     final long freeKb = memInfo.getFreeSizeKb();
16432                     final long zramKb = memInfo.getZramTotalSizeKb();
16433                     final long kernelKb = memInfo.getKernelUsedSizeKb();
16434                     EventLogTags.writeAmMeminfo(cachedKb*1024, freeKb*1024, zramKb*1024,
16435                             kernelKb*1024, nativeProcTotalPss*1024);
16436                     mProcessStats.addSysMemUsageLocked(cachedKb, freeKb, zramKb, kernelKb,
16437                             nativeProcTotalPss);
16438                 }
16439             }
16440             if (!brief) {
16441                 if (!isCompact) {
16442                     pw.print("Total RAM: "); pw.print(stringifyKBSize(memInfo.getTotalSizeKb()));
16443                     pw.print(" (status ");
16444                     switch (mLastMemoryLevel) {
16445                         case ProcessStats.ADJ_MEM_FACTOR_NORMAL:
16446                             pw.println("normal)");
16447                             break;
16448                         case ProcessStats.ADJ_MEM_FACTOR_MODERATE:
16449                             pw.println("moderate)");
16450                             break;
16451                         case ProcessStats.ADJ_MEM_FACTOR_LOW:
16452                             pw.println("low)");
16453                             break;
16454                         case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
16455                             pw.println("critical)");
16456                             break;
16457                         default:
16458                             pw.print(mLastMemoryLevel);
16459                             pw.println(")");
16460                             break;
16461                     }
16462                     pw.print(" Free RAM: ");
16463                     pw.print(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16464                             + memInfo.getFreeSizeKb()));
16465                     pw.print(" (");
16466                     pw.print(stringifyKBSize(cachedPss));
16467                     pw.print(" cached pss + ");
16468                     pw.print(stringifyKBSize(memInfo.getCachedSizeKb()));
16469                     pw.print(" cached kernel + ");
16470                     pw.print(stringifyKBSize(memInfo.getFreeSizeKb()));
16471                     pw.println(" free)");
16472                 } else {
16473                     pw.print("ram,"); pw.print(memInfo.getTotalSizeKb()); pw.print(",");
16474                     pw.print(cachedPss + memInfo.getCachedSizeKb()
16475                             + memInfo.getFreeSizeKb()); pw.print(",");
16476                     pw.println(totalPss - cachedPss);
16477                 }
16478             }
16479             long lostRAM = memInfo.getTotalSizeKb() - (totalPss - totalSwapPss)
16480                     - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16481                     - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb();
16482             if (!isCompact) {
16483                 pw.print(" Used RAM: "); pw.print(stringifyKBSize(totalPss - cachedPss
16484                         + memInfo.getKernelUsedSizeKb())); pw.print(" (");
16485                 pw.print(stringifyKBSize(totalPss - cachedPss)); pw.print(" used pss + ");
16486                 pw.print(stringifyKBSize(memInfo.getKernelUsedSizeKb())); pw.print(" kernel)\n");
16487                 pw.print(" Lost RAM: "); pw.println(stringifyKBSize(lostRAM));
16488             } else {
16489                 pw.print("lostram,"); pw.println(lostRAM);
16490             }
16491             if (!brief) {
16492                 if (memInfo.getZramTotalSizeKb() != 0) {
16493                     if (!isCompact) {
16494                         pw.print("     ZRAM: ");
16495                         pw.print(stringifyKBSize(memInfo.getZramTotalSizeKb()));
16496                                 pw.print(" physical used for ");
16497                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()
16498                                         - memInfo.getSwapFreeSizeKb()));
16499                                 pw.print(" in swap (");
16500                                 pw.print(stringifyKBSize(memInfo.getSwapTotalSizeKb()));
16501                                 pw.println(" total swap)");
16502                     } else {
16503                         pw.print("zram,"); pw.print(memInfo.getZramTotalSizeKb()); pw.print(",");
16504                                 pw.print(memInfo.getSwapTotalSizeKb()); pw.print(",");
16505                                 pw.println(memInfo.getSwapFreeSizeKb());
16506                     }
16507                 }
16508                 final long[] ksm = getKsmInfo();
16509                 if (!isCompact) {
16510                     if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16511                             || ksm[KSM_VOLATILE] != 0) {
16512                         pw.print("      KSM: "); pw.print(stringifyKBSize(ksm[KSM_SHARING]));
16513                                 pw.print(" saved from shared ");
16514                                 pw.print(stringifyKBSize(ksm[KSM_SHARED]));
16515                         pw.print("           "); pw.print(stringifyKBSize(ksm[KSM_UNSHARED]));
16516                                 pw.print(" unshared; ");
16517                                 pw.print(stringifyKBSize(
16518                                              ksm[KSM_VOLATILE])); pw.println(" volatile");
16519                     }
16520                     pw.print("   Tuning: ");
16521                     pw.print(ActivityManager.staticGetMemoryClass());
16522                     pw.print(" (large ");
16523                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16524                     pw.print("), oom ");
16525                     pw.print(stringifySize(
16526                                 mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ), 1024));
16527                     pw.print(", restore limit ");
16528                     pw.print(stringifyKBSize(mProcessList.getCachedRestoreThresholdKb()));
16529                     if (ActivityManager.isLowRamDeviceStatic()) {
16530                         pw.print(" (low-ram)");
16531                     }
16532                     if (ActivityManager.isHighEndGfx()) {
16533                         pw.print(" (high-end-gfx)");
16534                     }
16535                     pw.println();
16536                 } else {
16537                     pw.print("ksm,"); pw.print(ksm[KSM_SHARING]); pw.print(",");
16538                     pw.print(ksm[KSM_SHARED]); pw.print(","); pw.print(ksm[KSM_UNSHARED]);
16539                     pw.print(","); pw.println(ksm[KSM_VOLATILE]);
16540                     pw.print("tuning,");
16541                     pw.print(ActivityManager.staticGetMemoryClass());
16542                     pw.print(',');
16543                     pw.print(ActivityManager.staticGetLargeMemoryClass());
16544                     pw.print(',');
16545                     pw.print(mProcessList.getMemLevel(ProcessList.CACHED_APP_MAX_ADJ)/1024);
16546                     if (ActivityManager.isLowRamDeviceStatic()) {
16547                         pw.print(",low-ram");
16548                     }
16549                     if (ActivityManager.isHighEndGfx()) {
16550                         pw.print(",high-end-gfx");
16551                     }
16552                     pw.println();
16553                 }
16554             }
16555         }
16556     }
16557
16558     private void appendBasicMemEntry(StringBuilder sb, int oomAdj, int procState, long pss,
16559             long memtrack, String name) {
16560         sb.append("  ");
16561         sb.append(ProcessList.makeOomAdjString(oomAdj));
16562         sb.append(' ');
16563         sb.append(ProcessList.makeProcStateString(procState));
16564         sb.append(' ');
16565         ProcessList.appendRamKb(sb, pss);
16566         sb.append(": ");
16567         sb.append(name);
16568         if (memtrack > 0) {
16569             sb.append(" (");
16570             sb.append(stringifyKBSize(memtrack));
16571             sb.append(" memtrack)");
16572         }
16573     }
16574
16575     private void appendMemInfo(StringBuilder sb, ProcessMemInfo mi) {
16576         appendBasicMemEntry(sb, mi.oomAdj, mi.procState, mi.pss, mi.memtrack, mi.name);
16577         sb.append(" (pid ");
16578         sb.append(mi.pid);
16579         sb.append(") ");
16580         sb.append(mi.adjType);
16581         sb.append('\n');
16582         if (mi.adjReason != null) {
16583             sb.append("                      ");
16584             sb.append(mi.adjReason);
16585             sb.append('\n');
16586         }
16587     }
16588
16589     void reportMemUsage(ArrayList<ProcessMemInfo> memInfos) {
16590         final SparseArray<ProcessMemInfo> infoMap = new SparseArray<>(memInfos.size());
16591         for (int i=0, N=memInfos.size(); i<N; i++) {
16592             ProcessMemInfo mi = memInfos.get(i);
16593             infoMap.put(mi.pid, mi);
16594         }
16595         updateCpuStatsNow();
16596         long[] memtrackTmp = new long[1];
16597         final List<ProcessCpuTracker.Stats> stats;
16598         // Get a list of Stats that have vsize > 0
16599         synchronized (mProcessCpuTracker) {
16600             stats = mProcessCpuTracker.getStats((st) -> {
16601                 return st.vsize > 0;
16602             });
16603         }
16604         final int statsCount = stats.size();
16605         for (int i = 0; i < statsCount; i++) {
16606             ProcessCpuTracker.Stats st = stats.get(i);
16607             long pss = Debug.getPss(st.pid, null, memtrackTmp);
16608             if (pss > 0) {
16609                 if (infoMap.indexOfKey(st.pid) < 0) {
16610                     ProcessMemInfo mi = new ProcessMemInfo(st.name, st.pid,
16611                             ProcessList.NATIVE_ADJ, -1, "native", null);
16612                     mi.pss = pss;
16613                     mi.memtrack = memtrackTmp[0];
16614                     memInfos.add(mi);
16615                 }
16616             }
16617         }
16618
16619         long totalPss = 0;
16620         long totalMemtrack = 0;
16621         for (int i=0, N=memInfos.size(); i<N; i++) {
16622             ProcessMemInfo mi = memInfos.get(i);
16623             if (mi.pss == 0) {
16624                 mi.pss = Debug.getPss(mi.pid, null, memtrackTmp);
16625                 mi.memtrack = memtrackTmp[0];
16626             }
16627             totalPss += mi.pss;
16628             totalMemtrack += mi.memtrack;
16629         }
16630         Collections.sort(memInfos, new Comparator<ProcessMemInfo>() {
16631             @Override public int compare(ProcessMemInfo lhs, ProcessMemInfo rhs) {
16632                 if (lhs.oomAdj != rhs.oomAdj) {
16633                     return lhs.oomAdj < rhs.oomAdj ? -1 : 1;
16634                 }
16635                 if (lhs.pss != rhs.pss) {
16636                     return lhs.pss < rhs.pss ? 1 : -1;
16637                 }
16638                 return 0;
16639             }
16640         });
16641
16642         StringBuilder tag = new StringBuilder(128);
16643         StringBuilder stack = new StringBuilder(128);
16644         tag.append("Low on memory -- ");
16645         appendMemBucket(tag, totalPss, "total", false);
16646         appendMemBucket(stack, totalPss, "total", true);
16647
16648         StringBuilder fullNativeBuilder = new StringBuilder(1024);
16649         StringBuilder shortNativeBuilder = new StringBuilder(1024);
16650         StringBuilder fullJavaBuilder = new StringBuilder(1024);
16651
16652         boolean firstLine = true;
16653         int lastOomAdj = Integer.MIN_VALUE;
16654         long extraNativeRam = 0;
16655         long extraNativeMemtrack = 0;
16656         long cachedPss = 0;
16657         for (int i=0, N=memInfos.size(); i<N; i++) {
16658             ProcessMemInfo mi = memInfos.get(i);
16659
16660             if (mi.oomAdj >= ProcessList.CACHED_APP_MIN_ADJ) {
16661                 cachedPss += mi.pss;
16662             }
16663
16664             if (mi.oomAdj != ProcessList.NATIVE_ADJ
16665                     && (mi.oomAdj < ProcessList.SERVICE_ADJ
16666                             || mi.oomAdj == ProcessList.HOME_APP_ADJ
16667                             || mi.oomAdj == ProcessList.PREVIOUS_APP_ADJ)) {
16668                 if (lastOomAdj != mi.oomAdj) {
16669                     lastOomAdj = mi.oomAdj;
16670                     if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16671                         tag.append(" / ");
16672                     }
16673                     if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ) {
16674                         if (firstLine) {
16675                             stack.append(":");
16676                             firstLine = false;
16677                         }
16678                         stack.append("\n\t at ");
16679                     } else {
16680                         stack.append("$");
16681                     }
16682                 } else {
16683                     tag.append(" ");
16684                     stack.append("$");
16685                 }
16686                 if (mi.oomAdj <= ProcessList.FOREGROUND_APP_ADJ) {
16687                     appendMemBucket(tag, mi.pss, mi.name, false);
16688                 }
16689                 appendMemBucket(stack, mi.pss, mi.name, true);
16690                 if (mi.oomAdj >= ProcessList.FOREGROUND_APP_ADJ
16691                         && ((i+1) >= N || memInfos.get(i+1).oomAdj != lastOomAdj)) {
16692                     stack.append("(");
16693                     for (int k=0; k<DUMP_MEM_OOM_ADJ.length; k++) {
16694                         if (DUMP_MEM_OOM_ADJ[k] == mi.oomAdj) {
16695                             stack.append(DUMP_MEM_OOM_LABEL[k]);
16696                             stack.append(":");
16697                             stack.append(DUMP_MEM_OOM_ADJ[k]);
16698                         }
16699                     }
16700                     stack.append(")");
16701                 }
16702             }
16703
16704             appendMemInfo(fullNativeBuilder, mi);
16705             if (mi.oomAdj == ProcessList.NATIVE_ADJ) {
16706                 // The short form only has native processes that are >= 512K.
16707                 if (mi.pss >= 512) {
16708                     appendMemInfo(shortNativeBuilder, mi);
16709                 } else {
16710                     extraNativeRam += mi.pss;
16711                     extraNativeMemtrack += mi.memtrack;
16712                 }
16713             } else {
16714                 // Short form has all other details, but if we have collected RAM
16715                 // from smaller native processes let's dump a summary of that.
16716                 if (extraNativeRam > 0) {
16717                     appendBasicMemEntry(shortNativeBuilder, ProcessList.NATIVE_ADJ,
16718                             -1, extraNativeRam, extraNativeMemtrack, "(Other native)");
16719                     shortNativeBuilder.append('\n');
16720                     extraNativeRam = 0;
16721                 }
16722                 appendMemInfo(fullJavaBuilder, mi);
16723             }
16724         }
16725
16726         fullJavaBuilder.append("           ");
16727         ProcessList.appendRamKb(fullJavaBuilder, totalPss);
16728         fullJavaBuilder.append(": TOTAL");
16729         if (totalMemtrack > 0) {
16730             fullJavaBuilder.append(" (");
16731             fullJavaBuilder.append(stringifyKBSize(totalMemtrack));
16732             fullJavaBuilder.append(" memtrack)");
16733         } else {
16734         }
16735         fullJavaBuilder.append("\n");
16736
16737         MemInfoReader memInfo = new MemInfoReader();
16738         memInfo.readMemInfo();
16739         final long[] infos = memInfo.getRawInfo();
16740
16741         StringBuilder memInfoBuilder = new StringBuilder(1024);
16742         Debug.getMemInfo(infos);
16743         memInfoBuilder.append("  MemInfo: ");
16744         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SLAB])).append(" slab, ");
16745         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SHMEM])).append(" shmem, ");
16746         memInfoBuilder.append(stringifyKBSize(
16747                                   infos[Debug.MEMINFO_VM_ALLOC_USED])).append(" vm alloc, ");
16748         memInfoBuilder.append(stringifyKBSize(
16749                                   infos[Debug.MEMINFO_PAGE_TABLES])).append(" page tables ");
16750         memInfoBuilder.append(stringifyKBSize(
16751                                   infos[Debug.MEMINFO_KERNEL_STACK])).append(" kernel stack\n");
16752         memInfoBuilder.append("           ");
16753         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_BUFFERS])).append(" buffers, ");
16754         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_CACHED])).append(" cached, ");
16755         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_MAPPED])).append(" mapped, ");
16756         memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_FREE])).append(" free\n");
16757         if (infos[Debug.MEMINFO_ZRAM_TOTAL] != 0) {
16758             memInfoBuilder.append("  ZRAM: ");
16759             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_ZRAM_TOTAL]));
16760             memInfoBuilder.append(" RAM, ");
16761             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_TOTAL]));
16762             memInfoBuilder.append(" swap total, ");
16763             memInfoBuilder.append(stringifyKBSize(infos[Debug.MEMINFO_SWAP_FREE]));
16764             memInfoBuilder.append(" swap free\n");
16765         }
16766         final long[] ksm = getKsmInfo();
16767         if (ksm[KSM_SHARING] != 0 || ksm[KSM_SHARED] != 0 || ksm[KSM_UNSHARED] != 0
16768                 || ksm[KSM_VOLATILE] != 0) {
16769             memInfoBuilder.append("  KSM: ");
16770             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARING]));
16771             memInfoBuilder.append(" saved from shared ");
16772             memInfoBuilder.append(stringifyKBSize(ksm[KSM_SHARED]));
16773             memInfoBuilder.append("\n       ");
16774             memInfoBuilder.append(stringifyKBSize(ksm[KSM_UNSHARED]));
16775             memInfoBuilder.append(" unshared; ");
16776             memInfoBuilder.append(stringifyKBSize(ksm[KSM_VOLATILE]));
16777             memInfoBuilder.append(" volatile\n");
16778         }
16779         memInfoBuilder.append("  Free RAM: ");
16780         memInfoBuilder.append(stringifyKBSize(cachedPss + memInfo.getCachedSizeKb()
16781                 + memInfo.getFreeSizeKb()));
16782         memInfoBuilder.append("\n");
16783         memInfoBuilder.append("  Used RAM: ");
16784         memInfoBuilder.append(stringifyKBSize(
16785                                   totalPss - cachedPss + memInfo.getKernelUsedSizeKb()));
16786         memInfoBuilder.append("\n");
16787         memInfoBuilder.append("  Lost RAM: ");
16788         memInfoBuilder.append(stringifyKBSize(memInfo.getTotalSizeKb()
16789                 - totalPss - memInfo.getFreeSizeKb() - memInfo.getCachedSizeKb()
16790                 - memInfo.getKernelUsedSizeKb() - memInfo.getZramTotalSizeKb()));
16791         memInfoBuilder.append("\n");
16792         Slog.i(TAG, "Low on memory:");
16793         Slog.i(TAG, shortNativeBuilder.toString());
16794         Slog.i(TAG, fullJavaBuilder.toString());
16795         Slog.i(TAG, memInfoBuilder.toString());
16796
16797         StringBuilder dropBuilder = new StringBuilder(1024);
16798         /*
16799         StringWriter oomSw = new StringWriter();
16800         PrintWriter oomPw = new FastPrintWriter(oomSw, false, 256);
16801         StringWriter catSw = new StringWriter();
16802         PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16803         String[] emptyArgs = new String[] { };
16804         dumpApplicationMemoryUsage(null, oomPw, "  ", emptyArgs, true, catPw);
16805         oomPw.flush();
16806         String oomString = oomSw.toString();
16807         */
16808         dropBuilder.append("Low on memory:");
16809         dropBuilder.append(stack);
16810         dropBuilder.append('\n');
16811         dropBuilder.append(fullNativeBuilder);
16812         dropBuilder.append(fullJavaBuilder);
16813         dropBuilder.append('\n');
16814         dropBuilder.append(memInfoBuilder);
16815         dropBuilder.append('\n');
16816         /*
16817         dropBuilder.append(oomString);
16818         dropBuilder.append('\n');
16819         */
16820         StringWriter catSw = new StringWriter();
16821         synchronized (ActivityManagerService.this) {
16822             PrintWriter catPw = new FastPrintWriter(catSw, false, 256);
16823             String[] emptyArgs = new String[] { };
16824             catPw.println();
16825             dumpProcessesLocked(null, catPw, emptyArgs, 0, false, null);
16826             catPw.println();
16827             mServices.newServiceDumperLocked(null, catPw, emptyArgs, 0,
16828                     false, null).dumpLocked();
16829             catPw.println();
16830             dumpActivitiesLocked(null, catPw, emptyArgs, 0, false, false, null);
16831             catPw.flush();
16832         }
16833         dropBuilder.append(catSw.toString());
16834         addErrorToDropBox("lowmem", null, "system_server", null,
16835                 null, tag.toString(), dropBuilder.toString(), null, null);
16836         //Slog.i(TAG, "Sent to dropbox:");
16837         //Slog.i(TAG, dropBuilder.toString());
16838         synchronized (ActivityManagerService.this) {
16839             long now = SystemClock.uptimeMillis();
16840             if (mLastMemUsageReportTime < now) {
16841                 mLastMemUsageReportTime = now;
16842             }
16843         }
16844     }
16845
16846     /**
16847      * Searches array of arguments for the specified string
16848      * @param args array of argument strings
16849      * @param value value to search for
16850      * @return true if the value is contained in the array
16851      */
16852     private static boolean scanArgs(String[] args, String value) {
16853         if (args != null) {
16854             for (String arg : args) {
16855                 if (value.equals(arg)) {
16856                     return true;
16857                 }
16858             }
16859         }
16860         return false;
16861     }
16862
16863     private final boolean removeDyingProviderLocked(ProcessRecord proc,
16864             ContentProviderRecord cpr, boolean always) {
16865         final boolean inLaunching = mLaunchingProviders.contains(cpr);
16866
16867         if (!inLaunching || always) {
16868             synchronized (cpr) {
16869                 cpr.launchingApp = null;
16870                 cpr.notifyAll();
16871             }
16872             mProviderMap.removeProviderByClass(cpr.name, UserHandle.getUserId(cpr.uid));
16873             String names[] = cpr.info.authority.split(";");
16874             for (int j = 0; j < names.length; j++) {
16875                 mProviderMap.removeProviderByName(names[j], UserHandle.getUserId(cpr.uid));
16876             }
16877         }
16878
16879         for (int i = cpr.connections.size() - 1; i >= 0; i--) {
16880             ContentProviderConnection conn = cpr.connections.get(i);
16881             if (conn.waiting) {
16882                 // If this connection is waiting for the provider, then we don't
16883                 // need to mess with its process unless we are always removing
16884                 // or for some reason the provider is not currently launching.
16885                 if (inLaunching && !always) {
16886                     continue;
16887                 }
16888             }
16889             ProcessRecord capp = conn.client;
16890             conn.dead = true;
16891             if (conn.stableCount > 0) {
16892                 if (!capp.persistent && capp.thread != null
16893                         && capp.pid != 0
16894                         && capp.pid != MY_PID) {
16895                     capp.kill("depends on provider "
16896                             + cpr.name.flattenToShortString()
16897                             + " in dying proc " + (proc != null ? proc.processName : "??")
16898                             + " (adj " + (proc != null ? proc.setAdj : "??") + ")", true);
16899                 }
16900             } else if (capp.thread != null && conn.provider.provider != null) {
16901                 try {
16902                     capp.thread.unstableProviderDied(conn.provider.provider.asBinder());
16903                 } catch (RemoteException e) {
16904                 }
16905                 // In the protocol here, we don't expect the client to correctly
16906                 // clean up this connection, we'll just remove it.
16907                 cpr.connections.remove(i);
16908                 if (conn.client.conProviders.remove(conn)) {
16909                     stopAssociationLocked(capp.uid, capp.processName, cpr.uid, cpr.name);
16910                 }
16911             }
16912         }
16913
16914         if (inLaunching && always) {
16915             mLaunchingProviders.remove(cpr);
16916         }
16917         return inLaunching;
16918     }
16919
16920     /**
16921      * Main code for cleaning up a process when it has gone away.  This is
16922      * called both as a result of the process dying, or directly when stopping
16923      * a process when running in single process mode.
16924      *
16925      * @return Returns true if the given process has been restarted, so the
16926      * app that was passed in must remain on the process lists.
16927      */
16928     private final boolean cleanUpApplicationRecordLocked(ProcessRecord app,
16929             boolean restarting, boolean allowRestart, int index, boolean replacingPid) {
16930         Slog.d(TAG, "cleanUpApplicationRecord -- " + app.pid);
16931         if (index >= 0) {
16932             removeLruProcessLocked(app);
16933             ProcessList.remove(app.pid);
16934         }
16935
16936         mProcessesToGc.remove(app);
16937         mPendingPssProcesses.remove(app);
16938
16939         // Dismiss any open dialogs.
16940         if (app.crashDialog != null && !app.forceCrashReport) {
16941             app.crashDialog.dismiss();
16942             app.crashDialog = null;
16943         }
16944         if (app.anrDialog != null) {
16945             app.anrDialog.dismiss();
16946             app.anrDialog = null;
16947         }
16948         if (app.waitDialog != null) {
16949             app.waitDialog.dismiss();
16950             app.waitDialog = null;
16951         }
16952
16953         app.crashing = false;
16954         app.notResponding = false;
16955
16956         app.resetPackageList(mProcessStats);
16957         app.unlinkDeathRecipient();
16958         app.makeInactive(mProcessStats);
16959         app.waitingToKill = null;
16960         app.forcingToForeground = null;
16961         updateProcessForegroundLocked(app, false, false);
16962         app.foregroundActivities = false;
16963         app.hasShownUi = false;
16964         app.treatLikeActivity = false;
16965         app.hasAboveClient = false;
16966         app.hasClientActivities = false;
16967
16968         mServices.killServicesLocked(app, allowRestart);
16969
16970         boolean restart = false;
16971
16972         // Remove published content providers.
16973         for (int i = app.pubProviders.size() - 1; i >= 0; i--) {
16974             ContentProviderRecord cpr = app.pubProviders.valueAt(i);
16975             final boolean always = app.bad || !allowRestart;
16976             boolean inLaunching = removeDyingProviderLocked(app, cpr, always);
16977             if ((inLaunching || always) && cpr.hasConnectionOrHandle()) {
16978                 // We left the provider in the launching list, need to
16979                 // restart it.
16980                 restart = true;
16981             }
16982
16983             cpr.provider = null;
16984             cpr.proc = null;
16985         }
16986         app.pubProviders.clear();
16987
16988         // Take care of any launching providers waiting for this process.
16989         if (cleanupAppInLaunchingProvidersLocked(app, false)) {
16990             restart = true;
16991         }
16992
16993         // Unregister from connected content providers.
16994         if (!app.conProviders.isEmpty()) {
16995             for (int i = app.conProviders.size() - 1; i >= 0; i--) {
16996                 ContentProviderConnection conn = app.conProviders.get(i);
16997                 conn.provider.connections.remove(conn);
16998                 stopAssociationLocked(app.uid, app.processName, conn.provider.uid,
16999                         conn.provider.name);
17000             }
17001             app.conProviders.clear();
17002         }
17003
17004         // At this point there may be remaining entries in mLaunchingProviders
17005         // where we were the only one waiting, so they are no longer of use.
17006         // Look for these and clean up if found.
17007         // XXX Commented out for now.  Trying to figure out a way to reproduce
17008         // the actual situation to identify what is actually going on.
17009         if (false) {
17010             for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17011                 ContentProviderRecord cpr = mLaunchingProviders.get(i);
17012                 if (cpr.connections.size() <= 0 && !cpr.hasExternalProcessHandles()) {
17013                     synchronized (cpr) {
17014                         cpr.launchingApp = null;
17015                         cpr.notifyAll();
17016                     }
17017                 }
17018             }
17019         }
17020
17021         skipCurrentReceiverLocked(app);
17022
17023         // Unregister any receivers.
17024         for (int i = app.receivers.size() - 1; i >= 0; i--) {
17025             removeReceiverLocked(app.receivers.valueAt(i));
17026         }
17027         app.receivers.clear();
17028
17029         // If the app is undergoing backup, tell the backup manager about it
17030         if (mBackupTarget != null && app.pid == mBackupTarget.app.pid) {
17031             if (DEBUG_BACKUP || DEBUG_CLEANUP) Slog.d(TAG_CLEANUP, "App "
17032                     + mBackupTarget.appInfo + " died during backup");
17033             try {
17034                 IBackupManager bm = IBackupManager.Stub.asInterface(
17035                         ServiceManager.getService(Context.BACKUP_SERVICE));
17036                 bm.agentDisconnected(app.info.packageName);
17037             } catch (RemoteException e) {
17038                 // can't happen; backup manager is local
17039             }
17040         }
17041
17042         for (int i = mPendingProcessChanges.size() - 1; i >= 0; i--) {
17043             ProcessChangeItem item = mPendingProcessChanges.get(i);
17044             if (item.pid == app.pid) {
17045                 mPendingProcessChanges.remove(i);
17046                 mAvailProcessChanges.add(item);
17047             }
17048         }
17049         mUiHandler.obtainMessage(DISPATCH_PROCESS_DIED_UI_MSG, app.pid, app.info.uid,
17050                 null).sendToTarget();
17051
17052         // If the caller is restarting this app, then leave it in its
17053         // current lists and let the caller take care of it.
17054         if (restarting) {
17055             return false;
17056         }
17057
17058         if (!app.persistent || app.isolated) {
17059             if (DEBUG_PROCESSES || DEBUG_CLEANUP) Slog.v(TAG_CLEANUP,
17060                     "Removing non-persistent process during cleanup: " + app);
17061             if (!replacingPid) {
17062                 removeProcessNameLocked(app.processName, app.uid, app);
17063             }
17064             if (mHeavyWeightProcess == app) {
17065                 mHandler.sendMessage(mHandler.obtainMessage(CANCEL_HEAVY_NOTIFICATION_MSG,
17066                         mHeavyWeightProcess.userId, 0));
17067                 mHeavyWeightProcess = null;
17068             }
17069         } else if (!app.removed) {
17070             // This app is persistent, so we need to keep its record around.
17071             // If it is not already on the pending app list, add it there
17072             // and start a new process for it.
17073             if (mPersistentStartingProcesses.indexOf(app) < 0) {
17074                 mPersistentStartingProcesses.add(app);
17075                 restart = true;
17076             }
17077         }
17078         if ((DEBUG_PROCESSES || DEBUG_CLEANUP) && mProcessesOnHold.contains(app)) Slog.v(
17079                 TAG_CLEANUP, "Clean-up removing on hold: " + app);
17080         mProcessesOnHold.remove(app);
17081
17082         if (app == mHomeProcess) {
17083             mHomeProcess = null;
17084         }
17085         if (app == mPreviousProcess) {
17086             mPreviousProcess = null;
17087         }
17088
17089         if (restart && !app.isolated) {
17090             // We have components that still need to be running in the
17091             // process, so re-launch it.
17092             if (index < 0) {
17093                 ProcessList.remove(app.pid);
17094             }
17095             addProcessNameLocked(app);
17096             startProcessLocked(app, "restart", app.processName);
17097             return true;
17098         } else if (app.pid > 0 && app.pid != MY_PID) {
17099             // Goodbye!
17100             boolean removed;
17101             synchronized (mPidsSelfLocked) {
17102                 mPidsSelfLocked.remove(app.pid);
17103                 mHandler.removeMessages(PROC_START_TIMEOUT_MSG, app);
17104             }
17105             mBatteryStatsService.noteProcessFinish(app.processName, app.info.uid);
17106             if (app.isolated) {
17107                 mBatteryStatsService.removeIsolatedUid(app.uid, app.info.uid);
17108             }
17109             app.setPid(0);
17110         }
17111         return false;
17112     }
17113
17114     boolean checkAppInLaunchingProvidersLocked(ProcessRecord app) {
17115         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17116             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17117             if (cpr.launchingApp == app) {
17118                 return true;
17119             }
17120         }
17121         return false;
17122     }
17123
17124     boolean cleanupAppInLaunchingProvidersLocked(ProcessRecord app, boolean alwaysBad) {
17125         // Look through the content providers we are waiting to have launched,
17126         // and if any run in this process then either schedule a restart of
17127         // the process or kill the client waiting for it if this process has
17128         // gone bad.
17129         boolean restart = false;
17130         for (int i = mLaunchingProviders.size() - 1; i >= 0; i--) {
17131             ContentProviderRecord cpr = mLaunchingProviders.get(i);
17132             if (cpr.launchingApp == app) {
17133                 if (!alwaysBad && !app.bad && cpr.hasConnectionOrHandle()) {
17134                     restart = true;
17135                 } else {
17136                     removeDyingProviderLocked(app, cpr, true);
17137                 }
17138             }
17139         }
17140         return restart;
17141     }
17142
17143     // =========================================================
17144     // SERVICES
17145     // =========================================================
17146
17147     @Override
17148     public List<ActivityManager.RunningServiceInfo> getServices(int maxNum,
17149             int flags) {
17150         enforceNotIsolatedCaller("getServices");
17151         synchronized (this) {
17152             return mServices.getRunningServiceInfoLocked(maxNum, flags);
17153         }
17154     }
17155
17156     @Override
17157     public PendingIntent getRunningServiceControlPanel(ComponentName name) {
17158         enforceNotIsolatedCaller("getRunningServiceControlPanel");
17159         synchronized (this) {
17160             return mServices.getRunningServiceControlPanelLocked(name);
17161         }
17162     }
17163
17164     @Override
17165     public ComponentName startService(IApplicationThread caller, Intent service,
17166             String resolvedType, String callingPackage, int userId)
17167             throws TransactionTooLargeException {
17168         enforceNotIsolatedCaller("startService");
17169         // Refuse possible leaked file descriptors
17170         if (service != null && service.hasFileDescriptors() == true) {
17171             throw new IllegalArgumentException("File descriptors passed in Intent");
17172         }
17173
17174         if (callingPackage == null) {
17175             throw new IllegalArgumentException("callingPackage cannot be null");
17176         }
17177
17178         if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17179                 "startService: " + service + " type=" + resolvedType);
17180         synchronized(this) {
17181             final int callingPid = Binder.getCallingPid();
17182             final int callingUid = Binder.getCallingUid();
17183             final long origId = Binder.clearCallingIdentity();
17184             ComponentName res = mServices.startServiceLocked(caller, service,
17185                     resolvedType, callingPid, callingUid, callingPackage, userId);
17186             Binder.restoreCallingIdentity(origId);
17187             return res;
17188         }
17189     }
17190
17191     ComponentName startServiceInPackage(int uid, Intent service, String resolvedType,
17192             String callingPackage, int userId)
17193             throws TransactionTooLargeException {
17194         synchronized(this) {
17195             if (DEBUG_SERVICE) Slog.v(TAG_SERVICE,
17196                     "startServiceInPackage: " + service + " type=" + resolvedType);
17197             final long origId = Binder.clearCallingIdentity();
17198             ComponentName res = mServices.startServiceLocked(null, service,
17199                     resolvedType, -1, uid, callingPackage, userId);
17200             Binder.restoreCallingIdentity(origId);
17201             return res;
17202         }
17203     }
17204
17205     @Override
17206     public int stopService(IApplicationThread caller, Intent service,
17207             String resolvedType, int userId) {
17208         enforceNotIsolatedCaller("stopService");
17209         // Refuse possible leaked file descriptors
17210         if (service != null && service.hasFileDescriptors() == true) {
17211             throw new IllegalArgumentException("File descriptors passed in Intent");
17212         }
17213
17214         synchronized(this) {
17215             return mServices.stopServiceLocked(caller, service, resolvedType, userId);
17216         }
17217     }
17218
17219     @Override
17220     public IBinder peekService(Intent service, String resolvedType, String callingPackage) {
17221         enforceNotIsolatedCaller("peekService");
17222         // Refuse possible leaked file descriptors
17223         if (service != null && service.hasFileDescriptors() == true) {
17224             throw new IllegalArgumentException("File descriptors passed in Intent");
17225         }
17226
17227         if (callingPackage == null) {
17228             throw new IllegalArgumentException("callingPackage cannot be null");
17229         }
17230
17231         synchronized(this) {
17232             return mServices.peekServiceLocked(service, resolvedType, callingPackage);
17233         }
17234     }
17235
17236     @Override
17237     public boolean stopServiceToken(ComponentName className, IBinder token,
17238             int startId) {
17239         synchronized(this) {
17240             return mServices.stopServiceTokenLocked(className, token, startId);
17241         }
17242     }
17243
17244     @Override
17245     public void setServiceForeground(ComponentName className, IBinder token,
17246             int id, Notification notification, int flags) {
17247         synchronized(this) {
17248             mServices.setServiceForegroundLocked(className, token, id, notification, flags);
17249         }
17250     }
17251
17252     @Override
17253     public int handleIncomingUser(int callingPid, int callingUid, int userId, boolean allowAll,
17254             boolean requireFull, String name, String callerPackage) {
17255         return mUserController.handleIncomingUser(callingPid, callingUid, userId, allowAll,
17256                 requireFull ? ALLOW_FULL_ONLY : ALLOW_NON_FULL, name, callerPackage);
17257     }
17258
17259     boolean isSingleton(String componentProcessName, ApplicationInfo aInfo,
17260             String className, int flags) {
17261         boolean result = false;
17262         // For apps that don't have pre-defined UIDs, check for permission
17263         if (UserHandle.getAppId(aInfo.uid) >= Process.FIRST_APPLICATION_UID) {
17264             if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17265                 if (ActivityManager.checkUidPermission(
17266                         INTERACT_ACROSS_USERS,
17267                         aInfo.uid) != PackageManager.PERMISSION_GRANTED) {
17268                     ComponentName comp = new ComponentName(aInfo.packageName, className);
17269                     String msg = "Permission Denial: Component " + comp.flattenToShortString()
17270                             + " requests FLAG_SINGLE_USER, but app does not hold "
17271                             + INTERACT_ACROSS_USERS;
17272                     Slog.w(TAG, msg);
17273                     throw new SecurityException(msg);
17274                 }
17275                 // Permission passed
17276                 result = true;
17277             }
17278         } else if ("system".equals(componentProcessName)) {
17279             result = true;
17280         } else if ((flags & ServiceInfo.FLAG_SINGLE_USER) != 0) {
17281             // Phone app and persistent apps are allowed to export singleuser providers.
17282             result = UserHandle.isSameApp(aInfo.uid, Process.PHONE_UID)
17283                     || (aInfo.flags & ApplicationInfo.FLAG_PERSISTENT) != 0;
17284         }
17285         if (DEBUG_MU) Slog.v(TAG_MU,
17286                 "isSingleton(" + componentProcessName + ", " + aInfo + ", " + className + ", 0x"
17287                 + Integer.toHexString(flags) + ") = " + result);
17288         return result;
17289     }
17290
17291     /**
17292      * Checks to see if the caller is in the same app as the singleton
17293      * component, or the component is in a special app. It allows special apps
17294      * to export singleton components but prevents exporting singleton
17295      * components for regular apps.
17296      */
17297     boolean isValidSingletonCall(int callingUid, int componentUid) {
17298         int componentAppId = UserHandle.getAppId(componentUid);
17299         return UserHandle.isSameApp(callingUid, componentUid)
17300                 || componentAppId == Process.SYSTEM_UID
17301                 || componentAppId == Process.PHONE_UID
17302                 || ActivityManager.checkUidPermission(INTERACT_ACROSS_USERS_FULL, componentUid)
17303                         == PackageManager.PERMISSION_GRANTED;
17304     }
17305
17306     public int bindService(IApplicationThread caller, IBinder token, Intent service,
17307             String resolvedType, IServiceConnection connection, int flags, String callingPackage,
17308             int userId) throws TransactionTooLargeException {
17309         enforceNotIsolatedCaller("bindService");
17310
17311         // Refuse possible leaked file descriptors
17312         if (service != null && service.hasFileDescriptors() == true) {
17313             throw new IllegalArgumentException("File descriptors passed in Intent");
17314         }
17315
17316         if (callingPackage == null) {
17317             throw new IllegalArgumentException("callingPackage cannot be null");
17318         }
17319
17320         synchronized(this) {
17321             return mServices.bindServiceLocked(caller, token, service,
17322                     resolvedType, connection, flags, callingPackage, userId);
17323         }
17324     }
17325
17326     public boolean unbindService(IServiceConnection connection) {
17327         synchronized (this) {
17328             return mServices.unbindServiceLocked(connection);
17329         }
17330     }
17331
17332     public void publishService(IBinder token, Intent intent, IBinder service) {
17333         // Refuse possible leaked file descriptors
17334         if (intent != null && intent.hasFileDescriptors() == true) {
17335             throw new IllegalArgumentException("File descriptors passed in Intent");
17336         }
17337
17338         synchronized(this) {
17339             if (!(token instanceof ServiceRecord)) {
17340                 throw new IllegalArgumentException("Invalid service token");
17341             }
17342             mServices.publishServiceLocked((ServiceRecord)token, intent, service);
17343         }
17344     }
17345
17346     public void unbindFinished(IBinder token, Intent intent, boolean doRebind) {
17347         // Refuse possible leaked file descriptors
17348         if (intent != null && intent.hasFileDescriptors() == true) {
17349             throw new IllegalArgumentException("File descriptors passed in Intent");
17350         }
17351
17352         synchronized(this) {
17353             mServices.unbindFinishedLocked((ServiceRecord)token, intent, doRebind);
17354         }
17355     }
17356
17357     public void serviceDoneExecuting(IBinder token, int type, int startId, int res) {
17358         synchronized(this) {
17359             if (!(token instanceof ServiceRecord)) {
17360                 Slog.e(TAG, "serviceDoneExecuting: Invalid service token=" + token);
17361                 throw new IllegalArgumentException("Invalid service token");
17362             }
17363             mServices.serviceDoneExecutingLocked((ServiceRecord)token, type, startId, res);
17364         }
17365     }
17366
17367     // =========================================================
17368     // BACKUP AND RESTORE
17369     // =========================================================
17370
17371     // Cause the target app to be launched if necessary and its backup agent
17372     // instantiated.  The backup agent will invoke backupAgentCreated() on the
17373     // activity manager to announce its creation.
17374     public boolean bindBackupAgent(String packageName, int backupMode, int userId) {
17375         if (DEBUG_BACKUP) Slog.v(TAG, "bindBackupAgent: app=" + packageName + " mode=" + backupMode);
17376         enforceCallingPermission("android.permission.CONFIRM_FULL_BACKUP", "bindBackupAgent");
17377
17378         IPackageManager pm = AppGlobals.getPackageManager();
17379         ApplicationInfo app = null;
17380         try {
17381             app = pm.getApplicationInfo(packageName, 0, userId);
17382         } catch (RemoteException e) {
17383             // can't happen; package manager is process-local
17384         }
17385         if (app == null) {
17386             Slog.w(TAG, "Unable to bind backup agent for " + packageName);
17387             return false;
17388         }
17389
17390         synchronized(this) {
17391             // !!! TODO: currently no check here that we're already bound
17392             BatteryStatsImpl.Uid.Pkg.Serv ss = null;
17393             BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
17394             synchronized (stats) {
17395                 ss = stats.getServiceStatsLocked(app.uid, app.packageName, app.name);
17396             }
17397
17398             // Backup agent is now in use, its package can't be stopped.
17399             try {
17400                 AppGlobals.getPackageManager().setPackageStoppedState(
17401                         app.packageName, false, UserHandle.getUserId(app.uid));
17402             } catch (RemoteException e) {
17403             } catch (IllegalArgumentException e) {
17404                 Slog.w(TAG, "Failed trying to unstop package "
17405                         + app.packageName + ": " + e);
17406             }
17407
17408             BackupRecord r = new BackupRecord(ss, app, backupMode);
17409             ComponentName hostingName = (backupMode == IApplicationThread.BACKUP_MODE_INCREMENTAL)
17410                     ? new ComponentName(app.packageName, app.backupAgentName)
17411                     : new ComponentName("android", "FullBackupAgent");
17412             // startProcessLocked() returns existing proc's record if it's already running
17413             ProcessRecord proc = startProcessLocked(app.processName, app,
17414                     false, 0, "backup", hostingName, false, false, false);
17415             if (proc == null) {
17416                 Slog.e(TAG, "Unable to start backup agent process " + r);
17417                 return false;
17418             }
17419
17420             // If the app is a regular app (uid >= 10000) and not the system server or phone
17421             // process, etc, then mark it as being in full backup so that certain calls to the
17422             // process can be blocked. This is not reset to false anywhere because we kill the
17423             // process after the full backup is done and the ProcessRecord will vaporize anyway.
17424             if (UserHandle.isApp(app.uid) && backupMode == IApplicationThread.BACKUP_MODE_FULL) {
17425                 proc.inFullBackup = true;
17426             }
17427             r.app = proc;
17428             mBackupTarget = r;
17429             mBackupAppName = app.packageName;
17430
17431             // Try not to kill the process during backup
17432             updateOomAdjLocked(proc);
17433
17434             // If the process is already attached, schedule the creation of the backup agent now.
17435             // If it is not yet live, this will be done when it attaches to the framework.
17436             if (proc.thread != null) {
17437                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc already running: " + proc);
17438                 try {
17439                     proc.thread.scheduleCreateBackupAgent(app,
17440                             compatibilityInfoForPackageLocked(app), backupMode);
17441                 } catch (RemoteException e) {
17442                     // Will time out on the backup manager side
17443                 }
17444             } else {
17445                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "Agent proc not running, waiting for attach");
17446             }
17447             // Invariants: at this point, the target app process exists and the application
17448             // is either already running or in the process of coming up.  mBackupTarget and
17449             // mBackupAppName describe the app, so that when it binds back to the AM we
17450             // know that it's scheduled for a backup-agent operation.
17451         }
17452
17453         return true;
17454     }
17455
17456     @Override
17457     public void clearPendingBackup() {
17458         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "clearPendingBackup");
17459         enforceCallingPermission("android.permission.BACKUP", "clearPendingBackup");
17460
17461         synchronized (this) {
17462             mBackupTarget = null;
17463             mBackupAppName = null;
17464         }
17465     }
17466
17467     // A backup agent has just come up
17468     public void backupAgentCreated(String agentPackageName, IBinder agent) {
17469         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "backupAgentCreated: " + agentPackageName
17470                 + " = " + agent);
17471
17472         synchronized(this) {
17473             if (!agentPackageName.equals(mBackupAppName)) {
17474                 Slog.e(TAG, "Backup agent created for " + agentPackageName + " but not requested!");
17475                 return;
17476             }
17477         }
17478
17479         long oldIdent = Binder.clearCallingIdentity();
17480         try {
17481             IBackupManager bm = IBackupManager.Stub.asInterface(
17482                     ServiceManager.getService(Context.BACKUP_SERVICE));
17483             bm.agentConnected(agentPackageName, agent);
17484         } catch (RemoteException e) {
17485             // can't happen; the backup manager service is local
17486         } catch (Exception e) {
17487             Slog.w(TAG, "Exception trying to deliver BackupAgent binding: ");
17488             e.printStackTrace();
17489         } finally {
17490             Binder.restoreCallingIdentity(oldIdent);
17491         }
17492     }
17493
17494     // done with this agent
17495     public void unbindBackupAgent(ApplicationInfo appInfo) {
17496         if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "unbindBackupAgent: " + appInfo);
17497         if (appInfo == null) {
17498             Slog.w(TAG, "unbind backup agent for null app");
17499             return;
17500         }
17501
17502         synchronized(this) {
17503             try {
17504                 if (mBackupAppName == null) {
17505                     Slog.w(TAG, "Unbinding backup agent with no active backup");
17506                     return;
17507                 }
17508
17509                 if (!mBackupAppName.equals(appInfo.packageName)) {
17510                     Slog.e(TAG, "Unbind of " + appInfo + " but is not the current backup target");
17511                     return;
17512                 }
17513
17514                 // Not backing this app up any more; reset its OOM adjustment
17515                 final ProcessRecord proc = mBackupTarget.app;
17516                 updateOomAdjLocked(proc);
17517
17518                 // If the app crashed during backup, 'thread' will be null here
17519                 if (proc.thread != null) {
17520                     try {
17521                         proc.thread.scheduleDestroyBackupAgent(appInfo,
17522                                 compatibilityInfoForPackageLocked(appInfo));
17523                     } catch (Exception e) {
17524                         Slog.e(TAG, "Exception when unbinding backup agent:");
17525                         e.printStackTrace();
17526                     }
17527                 }
17528             } finally {
17529                 mBackupTarget = null;
17530                 mBackupAppName = null;
17531             }
17532         }
17533     }
17534     // =========================================================
17535     // BROADCASTS
17536     // =========================================================
17537
17538     boolean isPendingBroadcastProcessLocked(int pid) {
17539         return mFgBroadcastQueue.isPendingBroadcastProcessLocked(pid)
17540                 || mBgBroadcastQueue.isPendingBroadcastProcessLocked(pid);
17541     }
17542
17543     void skipPendingBroadcastLocked(int pid) {
17544             Slog.w(TAG, "Unattached app died before broadcast acknowledged, skipping");
17545             for (BroadcastQueue queue : mBroadcastQueues) {
17546                 queue.skipPendingBroadcastLocked(pid);
17547             }
17548     }
17549
17550     // The app just attached; send any pending broadcasts that it should receive
17551     boolean sendPendingBroadcastsLocked(ProcessRecord app) {
17552         boolean didSomething = false;
17553         for (BroadcastQueue queue : mBroadcastQueues) {
17554             didSomething |= queue.sendPendingBroadcastsLocked(app);
17555         }
17556         return didSomething;
17557     }
17558
17559     public Intent registerReceiver(IApplicationThread caller, String callerPackage,
17560             IIntentReceiver receiver, IntentFilter filter, String permission, int userId) {
17561         enforceNotIsolatedCaller("registerReceiver");
17562         ArrayList<Intent> stickyIntents = null;
17563         ProcessRecord callerApp = null;
17564         int callingUid;
17565         int callingPid;
17566         synchronized(this) {
17567             if (caller != null) {
17568                 callerApp = getRecordForAppLocked(caller);
17569                 if (callerApp == null) {
17570                     throw new SecurityException(
17571                             "Unable to find app for caller " + caller
17572                             + " (pid=" + Binder.getCallingPid()
17573                             + ") when registering receiver " + receiver);
17574                 }
17575                 if (callerApp.info.uid != Process.SYSTEM_UID &&
17576                         !callerApp.pkgList.containsKey(callerPackage) &&
17577                         !"android".equals(callerPackage)) {
17578                     throw new SecurityException("Given caller package " + callerPackage
17579                             + " is not running in process " + callerApp);
17580                 }
17581                 callingUid = callerApp.info.uid;
17582                 callingPid = callerApp.pid;
17583             } else {
17584                 callerPackage = null;
17585                 callingUid = Binder.getCallingUid();
17586                 callingPid = Binder.getCallingPid();
17587             }
17588
17589             userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17590                     ALLOW_FULL_ONLY, "registerReceiver", callerPackage);
17591
17592             Iterator<String> actions = filter.actionsIterator();
17593             if (actions == null) {
17594                 ArrayList<String> noAction = new ArrayList<String>(1);
17595                 noAction.add(null);
17596                 actions = noAction.iterator();
17597             }
17598
17599             // Collect stickies of users
17600             int[] userIds = { UserHandle.USER_ALL, UserHandle.getUserId(callingUid) };
17601             while (actions.hasNext()) {
17602                 String action = actions.next();
17603                 for (int id : userIds) {
17604                     ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(id);
17605                     if (stickies != null) {
17606                         ArrayList<Intent> intents = stickies.get(action);
17607                         if (intents != null) {
17608                             if (stickyIntents == null) {
17609                                 stickyIntents = new ArrayList<Intent>();
17610                             }
17611                             stickyIntents.addAll(intents);
17612                         }
17613                     }
17614                 }
17615             }
17616         }
17617
17618         ArrayList<Intent> allSticky = null;
17619         if (stickyIntents != null) {
17620             final ContentResolver resolver = mContext.getContentResolver();
17621             // Look for any matching sticky broadcasts...
17622             for (int i = 0, N = stickyIntents.size(); i < N; i++) {
17623                 Intent intent = stickyIntents.get(i);
17624                 // If intent has scheme "content", it will need to acccess
17625                 // provider that needs to lock mProviderMap in ActivityThread
17626                 // and also it may need to wait application response, so we
17627                 // cannot lock ActivityManagerService here.
17628                 if (filter.match(resolver, intent, true, TAG) >= 0) {
17629                     if (allSticky == null) {
17630                         allSticky = new ArrayList<Intent>();
17631                     }
17632                     allSticky.add(intent);
17633                 }
17634             }
17635         }
17636
17637         // The first sticky in the list is returned directly back to the client.
17638         Intent sticky = allSticky != null ? allSticky.get(0) : null;
17639         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Register receiver " + filter + ": " + sticky);
17640         if (receiver == null) {
17641             return sticky;
17642         }
17643
17644         synchronized (this) {
17645             if (callerApp != null && (callerApp.thread == null
17646                     || callerApp.thread.asBinder() != caller.asBinder())) {
17647                 // Original caller already died
17648                 return null;
17649             }
17650             ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17651             if (rl == null) {
17652                 rl = new ReceiverList(this, callerApp, callingPid, callingUid,
17653                         userId, receiver);
17654                 if (rl.app != null) {
17655                     rl.app.receivers.add(rl);
17656                 } else {
17657                     try {
17658                         receiver.asBinder().linkToDeath(rl, 0);
17659                     } catch (RemoteException e) {
17660                         return sticky;
17661                     }
17662                     rl.linkedToDeath = true;
17663                 }
17664                 mRegisteredReceivers.put(receiver.asBinder(), rl);
17665             } else if (rl.uid != callingUid) {
17666                 throw new IllegalArgumentException(
17667                         "Receiver requested to register for uid " + callingUid
17668                         + " was previously registered for uid " + rl.uid);
17669             } else if (rl.pid != callingPid) {
17670                 throw new IllegalArgumentException(
17671                         "Receiver requested to register for pid " + callingPid
17672                         + " was previously registered for pid " + rl.pid);
17673             } else if (rl.userId != userId) {
17674                 throw new IllegalArgumentException(
17675                         "Receiver requested to register for user " + userId
17676                         + " was previously registered for user " + rl.userId);
17677             }
17678             BroadcastFilter bf = new BroadcastFilter(filter, rl, callerPackage,
17679                     permission, callingUid, userId);
17680             rl.add(bf);
17681             if (!bf.debugCheck()) {
17682                 Slog.w(TAG, "==> For Dynamic broadcast");
17683             }
17684             mReceiverResolver.addFilter(bf);
17685
17686             // Enqueue broadcasts for all existing stickies that match
17687             // this filter.
17688             if (allSticky != null) {
17689                 ArrayList receivers = new ArrayList();
17690                 receivers.add(bf);
17691
17692                 final int stickyCount = allSticky.size();
17693                 for (int i = 0; i < stickyCount; i++) {
17694                     Intent intent = allSticky.get(i);
17695                     BroadcastQueue queue = broadcastQueueForIntent(intent);
17696                     BroadcastRecord r = new BroadcastRecord(queue, intent, null,
17697                             null, -1, -1, null, null, AppOpsManager.OP_NONE, null, receivers,
17698                             null, 0, null, null, false, true, true, -1);
17699                     queue.enqueueParallelBroadcastLocked(r);
17700                     queue.scheduleBroadcastsLocked();
17701                 }
17702             }
17703
17704             return sticky;
17705         }
17706     }
17707
17708     public void unregisterReceiver(IIntentReceiver receiver) {
17709         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Unregister receiver: " + receiver);
17710
17711         final long origId = Binder.clearCallingIdentity();
17712         try {
17713             boolean doTrim = false;
17714
17715             synchronized(this) {
17716                 ReceiverList rl = mRegisteredReceivers.get(receiver.asBinder());
17717                 if (rl != null) {
17718                     final BroadcastRecord r = rl.curBroadcast;
17719                     if (r != null && r == r.queue.getMatchingOrderedReceiver(r)) {
17720                         final boolean doNext = r.queue.finishReceiverLocked(
17721                                 r, r.resultCode, r.resultData, r.resultExtras,
17722                                 r.resultAbort, false);
17723                         if (doNext) {
17724                             doTrim = true;
17725                             r.queue.processNextBroadcast(false);
17726                         }
17727                     }
17728
17729                     if (rl.app != null) {
17730                         rl.app.receivers.remove(rl);
17731                     }
17732                     removeReceiverLocked(rl);
17733                     if (rl.linkedToDeath) {
17734                         rl.linkedToDeath = false;
17735                         rl.receiver.asBinder().unlinkToDeath(rl, 0);
17736                     }
17737                 }
17738             }
17739
17740             // If we actually concluded any broadcasts, we might now be able
17741             // to trim the recipients' apps from our working set
17742             if (doTrim) {
17743                 trimApplications();
17744                 return;
17745             }
17746
17747         } finally {
17748             Binder.restoreCallingIdentity(origId);
17749         }
17750     }
17751
17752     void removeReceiverLocked(ReceiverList rl) {
17753         mRegisteredReceivers.remove(rl.receiver.asBinder());
17754         for (int i = rl.size() - 1; i >= 0; i--) {
17755             mReceiverResolver.removeFilter(rl.get(i));
17756         }
17757     }
17758
17759     private final void sendPackageBroadcastLocked(int cmd, String[] packages, int userId) {
17760         for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
17761             ProcessRecord r = mLruProcesses.get(i);
17762             if (r.thread != null && (userId == UserHandle.USER_ALL || r.userId == userId)) {
17763                 try {
17764                     r.thread.dispatchPackageBroadcast(cmd, packages);
17765                 } catch (RemoteException ex) {
17766                 }
17767             }
17768         }
17769     }
17770
17771     private List<ResolveInfo> collectReceiverComponents(Intent intent, String resolvedType,
17772             int callingUid, int[] users) {
17773         // TODO: come back and remove this assumption to triage all broadcasts
17774         int pmFlags = STOCK_PM_FLAGS | MATCH_DEBUG_TRIAGED_MISSING;
17775
17776         List<ResolveInfo> receivers = null;
17777         try {
17778             HashSet<ComponentName> singleUserReceivers = null;
17779             boolean scannedFirstReceivers = false;
17780             for (int user : users) {
17781                 // Skip users that have Shell restrictions, with exception of always permitted
17782                 // Shell broadcasts
17783                 if (callingUid == Process.SHELL_UID
17784                         && mUserController.hasUserRestriction(
17785                                 UserManager.DISALLOW_DEBUGGING_FEATURES, user)
17786                         && !isPermittedShellBroadcast(intent)) {
17787                     continue;
17788                 }
17789                 List<ResolveInfo> newReceivers = AppGlobals.getPackageManager()
17790                         .queryIntentReceivers(intent, resolvedType, pmFlags, user).getList();
17791                 if (user != UserHandle.USER_SYSTEM && newReceivers != null) {
17792                     // If this is not the system user, we need to check for
17793                     // any receivers that should be filtered out.
17794                     for (int i=0; i<newReceivers.size(); i++) {
17795                         ResolveInfo ri = newReceivers.get(i);
17796                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SYSTEM_USER_ONLY) != 0) {
17797                             newReceivers.remove(i);
17798                             i--;
17799                         }
17800                     }
17801                 }
17802                 if (newReceivers != null && newReceivers.size() == 0) {
17803                     newReceivers = null;
17804                 }
17805                 if (receivers == null) {
17806                     receivers = newReceivers;
17807                 } else if (newReceivers != null) {
17808                     // We need to concatenate the additional receivers
17809                     // found with what we have do far.  This would be easy,
17810                     // but we also need to de-dup any receivers that are
17811                     // singleUser.
17812                     if (!scannedFirstReceivers) {
17813                         // Collect any single user receivers we had already retrieved.
17814                         scannedFirstReceivers = true;
17815                         for (int i=0; i<receivers.size(); i++) {
17816                             ResolveInfo ri = receivers.get(i);
17817                             if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17818                                 ComponentName cn = new ComponentName(
17819                                         ri.activityInfo.packageName, ri.activityInfo.name);
17820                                 if (singleUserReceivers == null) {
17821                                     singleUserReceivers = new HashSet<ComponentName>();
17822                                 }
17823                                 singleUserReceivers.add(cn);
17824                             }
17825                         }
17826                     }
17827                     // Add the new results to the existing results, tracking
17828                     // and de-dupping single user receivers.
17829                     for (int i=0; i<newReceivers.size(); i++) {
17830                         ResolveInfo ri = newReceivers.get(i);
17831                         if ((ri.activityInfo.flags&ActivityInfo.FLAG_SINGLE_USER) != 0) {
17832                             ComponentName cn = new ComponentName(
17833                                     ri.activityInfo.packageName, ri.activityInfo.name);
17834                             if (singleUserReceivers == null) {
17835                                 singleUserReceivers = new HashSet<ComponentName>();
17836                             }
17837                             if (!singleUserReceivers.contains(cn)) {
17838                                 singleUserReceivers.add(cn);
17839                                 receivers.add(ri);
17840                             }
17841                         } else {
17842                             receivers.add(ri);
17843                         }
17844                     }
17845                 }
17846             }
17847         } catch (RemoteException ex) {
17848             // pm is in same process, this will never happen.
17849         }
17850         return receivers;
17851     }
17852
17853     private boolean isPermittedShellBroadcast(Intent intent) {
17854         // remote bugreport should always be allowed to be taken
17855         return INTENT_REMOTE_BUGREPORT_FINISHED.equals(intent.getAction());
17856     }
17857
17858     private void checkBroadcastFromSystem(Intent intent, ProcessRecord callerApp,
17859             String callerPackage, int callingUid, boolean isProtectedBroadcast, List receivers) {
17860         final String action = intent.getAction();
17861         if (isProtectedBroadcast
17862                 || Intent.ACTION_CLOSE_SYSTEM_DIALOGS.equals(action)
17863                 || Intent.ACTION_DISMISS_KEYBOARD_SHORTCUTS.equals(action)
17864                 || Intent.ACTION_MEDIA_BUTTON.equals(action)
17865                 || Intent.ACTION_MEDIA_SCANNER_SCAN_FILE.equals(action)
17866                 || Intent.ACTION_SHOW_KEYBOARD_SHORTCUTS.equals(action)
17867                 || Intent.ACTION_MASTER_CLEAR.equals(action)
17868                 || AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
17869                 || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)
17870                 || LocationManager.HIGH_POWER_REQUEST_CHANGE_ACTION.equals(action)
17871                 || TelephonyIntents.ACTION_REQUEST_OMADM_CONFIGURATION_UPDATE.equals(action)
17872                 || SuggestionSpan.ACTION_SUGGESTION_PICKED.equals(action)) {
17873             // Broadcast is either protected, or it's a public action that
17874             // we've relaxed, so it's fine for system internals to send.
17875             return;
17876         }
17877
17878         // This broadcast may be a problem...  but there are often system components that
17879         // want to send an internal broadcast to themselves, which is annoying to have to
17880         // explicitly list each action as a protected broadcast, so we will check for that
17881         // one safe case and allow it: an explicit broadcast, only being received by something
17882         // that has protected itself.
17883         if (receivers != null && receivers.size() > 0
17884                 && (intent.getPackage() != null || intent.getComponent() != null)) {
17885             boolean allProtected = true;
17886             for (int i = receivers.size()-1; i >= 0; i--) {
17887                 Object target = receivers.get(i);
17888                 if (target instanceof ResolveInfo) {
17889                     ResolveInfo ri = (ResolveInfo)target;
17890                     if (ri.activityInfo.exported && ri.activityInfo.permission == null) {
17891                         allProtected = false;
17892                         break;
17893                     }
17894                 } else {
17895                     BroadcastFilter bf = (BroadcastFilter)target;
17896                     if (bf.requiredPermission == null) {
17897                         allProtected = false;
17898                         break;
17899                     }
17900                 }
17901             }
17902             if (allProtected) {
17903                 // All safe!
17904                 return;
17905             }
17906         }
17907
17908         // The vast majority of broadcasts sent from system internals
17909         // should be protected to avoid security holes, so yell loudly
17910         // to ensure we examine these cases.
17911         if (callerApp != null) {
17912             Log.wtf(TAG, "Sending non-protected broadcast " + action
17913                             + " from system " + callerApp.toShortString() + " pkg " + callerPackage,
17914                     new Throwable());
17915         } else {
17916             Log.wtf(TAG, "Sending non-protected broadcast " + action
17917                             + " from system uid " + UserHandle.formatUid(callingUid)
17918                             + " pkg " + callerPackage,
17919                     new Throwable());
17920         }
17921     }
17922
17923     final int broadcastIntentLocked(ProcessRecord callerApp,
17924             String callerPackage, Intent intent, String resolvedType,
17925             IIntentReceiver resultTo, int resultCode, String resultData,
17926             Bundle resultExtras, String[] requiredPermissions, int appOp, Bundle bOptions,
17927             boolean ordered, boolean sticky, int callingPid, int callingUid, int userId) {
17928         intent = new Intent(intent);
17929
17930         // By default broadcasts do not go to stopped apps.
17931         intent.addFlags(Intent.FLAG_EXCLUDE_STOPPED_PACKAGES);
17932
17933         // If we have not finished booting, don't allow this to launch new processes.
17934         if (!mProcessesReady && (intent.getFlags()&Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0) {
17935             intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
17936         }
17937
17938         if (DEBUG_BROADCAST_LIGHT) Slog.v(TAG_BROADCAST,
17939                 (sticky ? "Broadcast sticky: ": "Broadcast: ") + intent
17940                 + " ordered=" + ordered + " userid=" + userId);
17941         if ((resultTo != null) && !ordered) {
17942             Slog.w(TAG, "Broadcast " + intent + " not ordered but result callback requested!");
17943         }
17944
17945         userId = mUserController.handleIncomingUser(callingPid, callingUid, userId, true,
17946                 ALLOW_NON_FULL, "broadcast", callerPackage);
17947
17948         // Make sure that the user who is receiving this broadcast is running.
17949         // If not, we will just skip it. Make an exception for shutdown broadcasts
17950         // and upgrade steps.
17951
17952         if (userId != UserHandle.USER_ALL && !mUserController.isUserRunningLocked(userId, 0)) {
17953             if ((callingUid != Process.SYSTEM_UID
17954                     || (intent.getFlags() & Intent.FLAG_RECEIVER_BOOT_UPGRADE) == 0)
17955                     && !Intent.ACTION_SHUTDOWN.equals(intent.getAction())) {
17956                 Slog.w(TAG, "Skipping broadcast of " + intent
17957                         + ": user " + userId + " is stopped");
17958                 return ActivityManager.BROADCAST_FAILED_USER_STOPPED;
17959             }
17960         }
17961
17962         BroadcastOptions brOptions = null;
17963         if (bOptions != null) {
17964             brOptions = new BroadcastOptions(bOptions);
17965             if (brOptions.getTemporaryAppWhitelistDuration() > 0) {
17966                 // See if the caller is allowed to do this.  Note we are checking against
17967                 // the actual real caller (not whoever provided the operation as say a
17968                 // PendingIntent), because that who is actually supplied the arguments.
17969                 if (checkComponentPermission(
17970                         android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST,
17971                         Binder.getCallingPid(), Binder.getCallingUid(), -1, true)
17972                         != PackageManager.PERMISSION_GRANTED) {
17973                     String msg = "Permission Denial: " + intent.getAction()
17974                             + " broadcast from " + callerPackage + " (pid=" + callingPid
17975                             + ", uid=" + callingUid + ")"
17976                             + " requires "
17977                             + android.Manifest.permission.CHANGE_DEVICE_IDLE_TEMP_WHITELIST;
17978                     Slog.w(TAG, msg);
17979                     throw new SecurityException(msg);
17980                 }
17981             }
17982         }
17983
17984         // Verify that protected broadcasts are only being sent by system code,
17985         // and that system code is only sending protected broadcasts.
17986         final String action = intent.getAction();
17987         final boolean isProtectedBroadcast;
17988         try {
17989             isProtectedBroadcast = AppGlobals.getPackageManager().isProtectedBroadcast(action);
17990         } catch (RemoteException e) {
17991             Slog.w(TAG, "Remote exception", e);
17992             return ActivityManager.BROADCAST_SUCCESS;
17993         }
17994
17995         final boolean isCallerSystem;
17996         switch (UserHandle.getAppId(callingUid)) {
17997             case Process.ROOT_UID:
17998             case Process.SYSTEM_UID:
17999             case Process.PHONE_UID:
18000             case Process.BLUETOOTH_UID:
18001             case Process.NFC_UID:
18002                 isCallerSystem = true;
18003                 break;
18004             default:
18005                 isCallerSystem = (callerApp != null) && callerApp.persistent;
18006                 break;
18007         }
18008
18009         // First line security check before anything else: stop non-system apps from
18010         // sending protected broadcasts.
18011         if (!isCallerSystem) {
18012             if (isProtectedBroadcast) {
18013                 String msg = "Permission Denial: not allowed to send broadcast "
18014                         + action + " from pid="
18015                         + callingPid + ", uid=" + callingUid;
18016                 Slog.w(TAG, msg);
18017                 throw new SecurityException(msg);
18018
18019             } else if (AppWidgetManager.ACTION_APPWIDGET_CONFIGURE.equals(action)
18020                     || AppWidgetManager.ACTION_APPWIDGET_UPDATE.equals(action)) {
18021                 // Special case for compatibility: we don't want apps to send this,
18022                 // but historically it has not been protected and apps may be using it
18023                 // to poke their own app widget.  So, instead of making it protected,
18024                 // just limit it to the caller.
18025                 if (callerPackage == null) {
18026                     String msg = "Permission Denial: not allowed to send broadcast "
18027                             + action + " from unknown caller.";
18028                     Slog.w(TAG, msg);
18029                     throw new SecurityException(msg);
18030                 } else if (intent.getComponent() != null) {
18031                     // They are good enough to send to an explicit component...  verify
18032                     // it is being sent to the calling app.
18033                     if (!intent.getComponent().getPackageName().equals(
18034                             callerPackage)) {
18035                         String msg = "Permission Denial: not allowed to send broadcast "
18036                                 + action + " to "
18037                                 + intent.getComponent().getPackageName() + " from "
18038                                 + callerPackage;
18039                         Slog.w(TAG, msg);
18040                         throw new SecurityException(msg);
18041                     }
18042                 } else {
18043                     // Limit broadcast to their own package.
18044                     intent.setPackage(callerPackage);
18045                 }
18046             }
18047         }
18048
18049         if (action != null) {
18050             switch (action) {
18051                 case Intent.ACTION_UID_REMOVED:
18052                 case Intent.ACTION_PACKAGE_REMOVED:
18053                 case Intent.ACTION_PACKAGE_CHANGED:
18054                 case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18055                 case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18056                 case Intent.ACTION_PACKAGES_SUSPENDED:
18057                 case Intent.ACTION_PACKAGES_UNSUSPENDED:
18058                     // Handle special intents: if this broadcast is from the package
18059                     // manager about a package being removed, we need to remove all of
18060                     // its activities from the history stack.
18061                     if (checkComponentPermission(
18062                             android.Manifest.permission.BROADCAST_PACKAGE_REMOVED,
18063                             callingPid, callingUid, -1, true)
18064                             != PackageManager.PERMISSION_GRANTED) {
18065                         String msg = "Permission Denial: " + intent.getAction()
18066                                 + " broadcast from " + callerPackage + " (pid=" + callingPid
18067                                 + ", uid=" + callingUid + ")"
18068                                 + " requires "
18069                                 + android.Manifest.permission.BROADCAST_PACKAGE_REMOVED;
18070                         Slog.w(TAG, msg);
18071                         throw new SecurityException(msg);
18072                     }
18073                     switch (action) {
18074                         case Intent.ACTION_UID_REMOVED:
18075                             final Bundle intentExtras = intent.getExtras();
18076                             final int uid = intentExtras != null
18077                                     ? intentExtras.getInt(Intent.EXTRA_UID) : -1;
18078                             if (uid >= 0) {
18079                                 mBatteryStatsService.removeUid(uid);
18080                                 mAppOpsService.uidRemoved(uid);
18081                             }
18082                             break;
18083                         case Intent.ACTION_EXTERNAL_APPLICATIONS_UNAVAILABLE:
18084                             // If resources are unavailable just force stop all those packages
18085                             // and flush the attribute cache as well.
18086                             String list[] =
18087                                     intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18088                             if (list != null && list.length > 0) {
18089                                 for (int i = 0; i < list.length; i++) {
18090                                     forceStopPackageLocked(list[i], -1, false, true, true,
18091                                             false, false, userId, "storage unmount");
18092                                 }
18093                                 mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18094                                 sendPackageBroadcastLocked(
18095                                         IApplicationThread.EXTERNAL_STORAGE_UNAVAILABLE, list,
18096                                         userId);
18097                             }
18098                             break;
18099                         case Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE:
18100                             mRecentTasks.cleanupLocked(UserHandle.USER_ALL);
18101                             break;
18102                         case Intent.ACTION_PACKAGE_REMOVED:
18103                         case Intent.ACTION_PACKAGE_CHANGED:
18104                             Uri data = intent.getData();
18105                             String ssp;
18106                             if (data != null && (ssp=data.getSchemeSpecificPart()) != null) {
18107                                 boolean removed = Intent.ACTION_PACKAGE_REMOVED.equals(action);
18108                                 final boolean replacing =
18109                                         intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18110                                 final boolean killProcess =
18111                                         !intent.getBooleanExtra(Intent.EXTRA_DONT_KILL_APP, false);
18112                                 final boolean fullUninstall = removed && !replacing;
18113                                 if (removed) {
18114                                     if (killProcess) {
18115                                         forceStopPackageLocked(ssp, UserHandle.getAppId(
18116                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18117                                                 false, true, true, false, fullUninstall, userId,
18118                                                 removed ? "pkg removed" : "pkg changed");
18119                                     }
18120                                     final int cmd = killProcess
18121                                             ? IApplicationThread.PACKAGE_REMOVED
18122                                             : IApplicationThread.PACKAGE_REMOVED_DONT_KILL;
18123                                     sendPackageBroadcastLocked(cmd,
18124                                             new String[] {ssp}, userId);
18125                                     if (fullUninstall) {
18126                                         mAppOpsService.packageRemoved(
18127                                                 intent.getIntExtra(Intent.EXTRA_UID, -1), ssp);
18128
18129                                         // Remove all permissions granted from/to this package
18130                                         removeUriPermissionsForPackageLocked(ssp, userId, true);
18131
18132                                         removeTasksByPackageNameLocked(ssp, userId);
18133
18134                                         // Hide the "unsupported display" dialog if necessary.
18135                                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18136                                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18137                                             mUnsupportedDisplaySizeDialog.dismiss();
18138                                             mUnsupportedDisplaySizeDialog = null;
18139                                         }
18140                                         mCompatModePackages.handlePackageUninstalledLocked(ssp);
18141                                         mBatteryStatsService.notePackageUninstalled(ssp);
18142                                     }
18143                                 } else {
18144                                     if (killProcess) {
18145                                         killPackageProcessesLocked(ssp, UserHandle.getAppId(
18146                                                 intent.getIntExtra(Intent.EXTRA_UID, -1)),
18147                                                 userId, ProcessList.INVALID_ADJ,
18148                                                 false, true, true, false, "change " + ssp);
18149                                     }
18150                                     cleanupDisabledPackageComponentsLocked(ssp, userId, killProcess,
18151                                             intent.getStringArrayExtra(
18152                                                     Intent.EXTRA_CHANGED_COMPONENT_NAME_LIST));
18153                                 }
18154                             }
18155                             break;
18156                         case Intent.ACTION_PACKAGES_SUSPENDED:
18157                         case Intent.ACTION_PACKAGES_UNSUSPENDED:
18158                             final boolean suspended = Intent.ACTION_PACKAGES_SUSPENDED.equals(
18159                                     intent.getAction());
18160                             final String[] packageNames = intent.getStringArrayExtra(
18161                                     Intent.EXTRA_CHANGED_PACKAGE_LIST);
18162                             final int userHandle = intent.getIntExtra(
18163                                     Intent.EXTRA_USER_HANDLE, UserHandle.USER_NULL);
18164
18165                             synchronized(ActivityManagerService.this) {
18166                                 mRecentTasks.onPackagesSuspendedChanged(
18167                                         packageNames, suspended, userHandle);
18168                             }
18169                             break;
18170                     }
18171                     break;
18172                 case Intent.ACTION_PACKAGE_REPLACED:
18173                 {
18174                     final Uri data = intent.getData();
18175                     final String ssp;
18176                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18177                         final ApplicationInfo aInfo =
18178                                 getPackageManagerInternalLocked().getApplicationInfo(
18179                                         ssp,
18180                                         userId);
18181                         if (aInfo == null) {
18182                             Slog.w(TAG, "Dropping ACTION_PACKAGE_REPLACED for non-existent pkg:"
18183                                     + " ssp=" + ssp + " data=" + data);
18184                             return ActivityManager.BROADCAST_SUCCESS;
18185                         }
18186                         mStackSupervisor.updateActivityApplicationInfoLocked(aInfo);
18187                         sendPackageBroadcastLocked(IApplicationThread.PACKAGE_REPLACED,
18188                                 new String[] {ssp}, userId);
18189                     }
18190                     break;
18191                 }
18192                 case Intent.ACTION_PACKAGE_ADDED:
18193                 {
18194                     // Special case for adding a package: by default turn on compatibility mode.
18195                     Uri data = intent.getData();
18196                     String ssp;
18197                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18198                         final boolean replacing =
18199                                 intent.getBooleanExtra(Intent.EXTRA_REPLACING, false);
18200                         mCompatModePackages.handlePackageAddedLocked(ssp, replacing);
18201
18202                         try {
18203                             ApplicationInfo ai = AppGlobals.getPackageManager().
18204                                     getApplicationInfo(ssp, 0, 0);
18205                             mBatteryStatsService.notePackageInstalled(ssp,
18206                                     ai != null ? ai.versionCode : 0);
18207                         } catch (RemoteException e) {
18208                         }
18209                     }
18210                     break;
18211                 }
18212                 case Intent.ACTION_PACKAGE_DATA_CLEARED:
18213                 {
18214                     Uri data = intent.getData();
18215                     String ssp;
18216                     if (data != null && (ssp = data.getSchemeSpecificPart()) != null) {
18217                         // Hide the "unsupported display" dialog if necessary.
18218                         if (mUnsupportedDisplaySizeDialog != null && ssp.equals(
18219                                 mUnsupportedDisplaySizeDialog.getPackageName())) {
18220                             mUnsupportedDisplaySizeDialog.dismiss();
18221                             mUnsupportedDisplaySizeDialog = null;
18222                         }
18223                         mCompatModePackages.handlePackageDataClearedLocked(ssp);
18224                     }
18225                     break;
18226                 }
18227                 case Intent.ACTION_TIMEZONE_CHANGED:
18228                     // If this is the time zone changed action, queue up a message that will reset
18229                     // the timezone of all currently running processes. This message will get
18230                     // queued up before the broadcast happens.
18231                     mHandler.sendEmptyMessage(UPDATE_TIME_ZONE);
18232                     break;
18233                 case Intent.ACTION_TIME_CHANGED:
18234                     // If the user set the time, let all running processes know.
18235                     final int is24Hour =
18236                             intent.getBooleanExtra(Intent.EXTRA_TIME_PREF_24_HOUR_FORMAT, false) ? 1
18237                                     : 0;
18238                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_TIME, is24Hour, 0));
18239                     BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
18240                     synchronized (stats) {
18241                         stats.noteCurrentTimeChangedLocked();
18242                     }
18243                     break;
18244                 case Intent.ACTION_CLEAR_DNS_CACHE:
18245                     mHandler.sendEmptyMessage(CLEAR_DNS_CACHE_MSG);
18246                     break;
18247                 case Proxy.PROXY_CHANGE_ACTION:
18248                     ProxyInfo proxy = intent.getParcelableExtra(Proxy.EXTRA_PROXY_INFO);
18249                     mHandler.sendMessage(mHandler.obtainMessage(UPDATE_HTTP_PROXY_MSG, proxy));
18250                     break;
18251                 case android.hardware.Camera.ACTION_NEW_PICTURE:
18252                 case android.hardware.Camera.ACTION_NEW_VIDEO:
18253                     // These broadcasts are no longer allowed by the system, since they can
18254                     // cause significant thrashing at a crictical point (using the camera).
18255                     // Apps should use JobScehduler to monitor for media provider changes.
18256                     Slog.w(TAG, action + " no longer allowed; dropping from "
18257                             + UserHandle.formatUid(callingUid));
18258                     if (resultTo != null) {
18259                         final BroadcastQueue queue = broadcastQueueForIntent(intent);
18260                         try {
18261                             queue.performReceiveLocked(callerApp, resultTo, intent,
18262                                     Activity.RESULT_CANCELED, null, null,
18263                                     false, false, userId);
18264                         } catch (RemoteException e) {
18265                             Slog.w(TAG, "Failure ["
18266                                     + queue.mQueueName + "] sending broadcast result of "
18267                                     + intent, e);
18268
18269                         }
18270                     }
18271                     // Lie; we don't want to crash the app.
18272                     return ActivityManager.BROADCAST_SUCCESS;
18273             }
18274         }
18275
18276         // Add to the sticky list if requested.
18277         if (sticky) {
18278             if (checkPermission(android.Manifest.permission.BROADCAST_STICKY,
18279                     callingPid, callingUid)
18280                     != PackageManager.PERMISSION_GRANTED) {
18281                 String msg = "Permission Denial: broadcastIntent() requesting a sticky broadcast from pid="
18282                         + callingPid + ", uid=" + callingUid
18283                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18284                 Slog.w(TAG, msg);
18285                 throw new SecurityException(msg);
18286             }
18287             if (requiredPermissions != null && requiredPermissions.length > 0) {
18288                 Slog.w(TAG, "Can't broadcast sticky intent " + intent
18289                         + " and enforce permissions " + Arrays.toString(requiredPermissions));
18290                 return ActivityManager.BROADCAST_STICKY_CANT_HAVE_PERMISSION;
18291             }
18292             if (intent.getComponent() != null) {
18293                 throw new SecurityException(
18294                         "Sticky broadcasts can't target a specific component");
18295             }
18296             // We use userId directly here, since the "all" target is maintained
18297             // as a separate set of sticky broadcasts.
18298             if (userId != UserHandle.USER_ALL) {
18299                 // But first, if this is not a broadcast to all users, then
18300                 // make sure it doesn't conflict with an existing broadcast to
18301                 // all users.
18302                 ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(
18303                         UserHandle.USER_ALL);
18304                 if (stickies != null) {
18305                     ArrayList<Intent> list = stickies.get(intent.getAction());
18306                     if (list != null) {
18307                         int N = list.size();
18308                         int i;
18309                         for (i=0; i<N; i++) {
18310                             if (intent.filterEquals(list.get(i))) {
18311                                 throw new IllegalArgumentException(
18312                                         "Sticky broadcast " + intent + " for user "
18313                                         + userId + " conflicts with existing global broadcast");
18314                             }
18315                         }
18316                     }
18317                 }
18318             }
18319             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18320             if (stickies == null) {
18321                 stickies = new ArrayMap<>();
18322                 mStickyBroadcasts.put(userId, stickies);
18323             }
18324             ArrayList<Intent> list = stickies.get(intent.getAction());
18325             if (list == null) {
18326                 list = new ArrayList<>();
18327                 stickies.put(intent.getAction(), list);
18328             }
18329             final int stickiesCount = list.size();
18330             int i;
18331             for (i = 0; i < stickiesCount; i++) {
18332                 if (intent.filterEquals(list.get(i))) {
18333                     // This sticky already exists, replace it.
18334                     list.set(i, new Intent(intent));
18335                     break;
18336                 }
18337             }
18338             if (i >= stickiesCount) {
18339                 list.add(new Intent(intent));
18340             }
18341         }
18342
18343         int[] users;
18344         if (userId == UserHandle.USER_ALL) {
18345             // Caller wants broadcast to go to all started users.
18346             users = mUserController.getStartedUserArrayLocked();
18347         } else {
18348             // Caller wants broadcast to go to one specific user.
18349             users = new int[] {userId};
18350         }
18351
18352         // Figure out who all will receive this broadcast.
18353         List receivers = null;
18354         List<BroadcastFilter> registeredReceivers = null;
18355         // Need to resolve the intent to interested receivers...
18356         if ((intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY)
18357                  == 0) {
18358             receivers = collectReceiverComponents(intent, resolvedType, callingUid, users);
18359         }
18360         if (intent.getComponent() == null) {
18361             if (userId == UserHandle.USER_ALL && callingUid == Process.SHELL_UID) {
18362                 // Query one target user at a time, excluding shell-restricted users
18363                 for (int i = 0; i < users.length; i++) {
18364                     if (mUserController.hasUserRestriction(
18365                             UserManager.DISALLOW_DEBUGGING_FEATURES, users[i])) {
18366                         continue;
18367                     }
18368                     List<BroadcastFilter> registeredReceiversForUser =
18369                             mReceiverResolver.queryIntent(intent,
18370                                     resolvedType, false, users[i]);
18371                     if (registeredReceivers == null) {
18372                         registeredReceivers = registeredReceiversForUser;
18373                     } else if (registeredReceiversForUser != null) {
18374                         registeredReceivers.addAll(registeredReceiversForUser);
18375                     }
18376                 }
18377             } else {
18378                 registeredReceivers = mReceiverResolver.queryIntent(intent,
18379                         resolvedType, false, userId);
18380             }
18381         }
18382
18383         final boolean replacePending =
18384                 (intent.getFlags()&Intent.FLAG_RECEIVER_REPLACE_PENDING) != 0;
18385
18386         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueing broadcast: " + intent.getAction()
18387                 + " replacePending=" + replacePending);
18388
18389         int NR = registeredReceivers != null ? registeredReceivers.size() : 0;
18390         if (!ordered && NR > 0) {
18391             // If we are not serializing this broadcast, then send the
18392             // registered receivers separately so they don't wait for the
18393             // components to be launched.
18394             if (isCallerSystem) {
18395                 checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18396                         isProtectedBroadcast, registeredReceivers);
18397             }
18398             final BroadcastQueue queue = broadcastQueueForIntent(intent);
18399             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18400                     callerPackage, callingPid, callingUid, resolvedType, requiredPermissions,
18401                     appOp, brOptions, registeredReceivers, resultTo, resultCode, resultData,
18402                     resultExtras, ordered, sticky, false, userId);
18403             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing parallel broadcast " + r);
18404             final boolean replaced = replacePending && queue.replaceParallelBroadcastLocked(r);
18405             if (!replaced) {
18406                 queue.enqueueParallelBroadcastLocked(r);
18407                 queue.scheduleBroadcastsLocked();
18408             }
18409             registeredReceivers = null;
18410             NR = 0;
18411         }
18412
18413         // Merge into one list.
18414         int ir = 0;
18415         if (receivers != null) {
18416             // A special case for PACKAGE_ADDED: do not allow the package
18417             // being added to see this broadcast.  This prevents them from
18418             // using this as a back door to get run as soon as they are
18419             // installed.  Maybe in the future we want to have a special install
18420             // broadcast or such for apps, but we'd like to deliberately make
18421             // this decision.
18422             String skipPackages[] = null;
18423             if (Intent.ACTION_PACKAGE_ADDED.equals(intent.getAction())
18424                     || Intent.ACTION_PACKAGE_RESTARTED.equals(intent.getAction())
18425                     || Intent.ACTION_PACKAGE_DATA_CLEARED.equals(intent.getAction())) {
18426                 Uri data = intent.getData();
18427                 if (data != null) {
18428                     String pkgName = data.getSchemeSpecificPart();
18429                     if (pkgName != null) {
18430                         skipPackages = new String[] { pkgName };
18431                     }
18432                 }
18433             } else if (Intent.ACTION_EXTERNAL_APPLICATIONS_AVAILABLE.equals(intent.getAction())) {
18434                 skipPackages = intent.getStringArrayExtra(Intent.EXTRA_CHANGED_PACKAGE_LIST);
18435             }
18436             if (skipPackages != null && (skipPackages.length > 0)) {
18437                 for (String skipPackage : skipPackages) {
18438                     if (skipPackage != null) {
18439                         int NT = receivers.size();
18440                         for (int it=0; it<NT; it++) {
18441                             ResolveInfo curt = (ResolveInfo)receivers.get(it);
18442                             if (curt.activityInfo.packageName.equals(skipPackage)) {
18443                                 receivers.remove(it);
18444                                 it--;
18445                                 NT--;
18446                             }
18447                         }
18448                     }
18449                 }
18450             }
18451
18452             int NT = receivers != null ? receivers.size() : 0;
18453             int it = 0;
18454             ResolveInfo curt = null;
18455             BroadcastFilter curr = null;
18456             while (it < NT && ir < NR) {
18457                 if (curt == null) {
18458                     curt = (ResolveInfo)receivers.get(it);
18459                 }
18460                 if (curr == null) {
18461                     curr = registeredReceivers.get(ir);
18462                 }
18463                 if (curr.getPriority() >= curt.priority) {
18464                     // Insert this broadcast record into the final list.
18465                     receivers.add(it, curr);
18466                     ir++;
18467                     curr = null;
18468                     it++;
18469                     NT++;
18470                 } else {
18471                     // Skip to the next ResolveInfo in the final list.
18472                     it++;
18473                     curt = null;
18474                 }
18475             }
18476         }
18477         while (ir < NR) {
18478             if (receivers == null) {
18479                 receivers = new ArrayList();
18480             }
18481             receivers.add(registeredReceivers.get(ir));
18482             ir++;
18483         }
18484
18485         if (isCallerSystem) {
18486             checkBroadcastFromSystem(intent, callerApp, callerPackage, callingUid,
18487                     isProtectedBroadcast, receivers);
18488         }
18489
18490         if ((receivers != null && receivers.size() > 0)
18491                 || resultTo != null) {
18492             BroadcastQueue queue = broadcastQueueForIntent(intent);
18493             BroadcastRecord r = new BroadcastRecord(queue, intent, callerApp,
18494                     callerPackage, callingPid, callingUid, resolvedType,
18495                     requiredPermissions, appOp, brOptions, receivers, resultTo, resultCode,
18496                     resultData, resultExtras, ordered, sticky, false, userId);
18497
18498             if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Enqueueing ordered broadcast " + r
18499                     + ": prev had " + queue.mOrderedBroadcasts.size());
18500             if (DEBUG_BROADCAST) Slog.i(TAG_BROADCAST,
18501                     "Enqueueing broadcast " + r.intent.getAction());
18502
18503             boolean replaced = replacePending && queue.replaceOrderedBroadcastLocked(r);
18504             if (!replaced) {
18505                 queue.enqueueOrderedBroadcastLocked(r);
18506                 queue.scheduleBroadcastsLocked();
18507             }
18508         } else {
18509             // There was nobody interested in the broadcast, but we still want to record
18510             // that it happened.
18511             if (intent.getComponent() == null && intent.getPackage() == null
18512                     && (intent.getFlags()&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18513                 // This was an implicit broadcast... let's record it for posterity.
18514                 addBroadcastStatLocked(intent.getAction(), callerPackage, 0, 0, 0);
18515             }
18516         }
18517
18518         return ActivityManager.BROADCAST_SUCCESS;
18519     }
18520
18521     final void addBroadcastStatLocked(String action, String srcPackage, int receiveCount,
18522             int skipCount, long dispatchTime) {
18523         final long now = SystemClock.elapsedRealtime();
18524         if (mCurBroadcastStats == null ||
18525                 (mCurBroadcastStats.mStartRealtime +(24*60*60*1000) < now)) {
18526             mLastBroadcastStats = mCurBroadcastStats;
18527             if (mLastBroadcastStats != null) {
18528                 mLastBroadcastStats.mEndRealtime = SystemClock.elapsedRealtime();
18529                 mLastBroadcastStats.mEndUptime = SystemClock.uptimeMillis();
18530             }
18531             mCurBroadcastStats = new BroadcastStats();
18532         }
18533         mCurBroadcastStats.addBroadcast(action, srcPackage, receiveCount, skipCount, dispatchTime);
18534     }
18535
18536     final Intent verifyBroadcastLocked(Intent intent) {
18537         // Refuse possible leaked file descriptors
18538         if (intent != null && intent.hasFileDescriptors() == true) {
18539             throw new IllegalArgumentException("File descriptors passed in Intent");
18540         }
18541
18542         int flags = intent.getFlags();
18543
18544         if (!mProcessesReady) {
18545             // if the caller really truly claims to know what they're doing, go
18546             // ahead and allow the broadcast without launching any receivers
18547             if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY_BEFORE_BOOT) != 0) {
18548                 // This will be turned into a FLAG_RECEIVER_REGISTERED_ONLY later on if needed.
18549             } else if ((flags&Intent.FLAG_RECEIVER_REGISTERED_ONLY) == 0) {
18550                 Slog.e(TAG, "Attempt to launch receivers of broadcast intent " + intent
18551                         + " before boot completion");
18552                 throw new IllegalStateException("Cannot broadcast before boot completed");
18553             }
18554         }
18555
18556         if ((flags&Intent.FLAG_RECEIVER_BOOT_UPGRADE) != 0) {
18557             throw new IllegalArgumentException(
18558                     "Can't use FLAG_RECEIVER_BOOT_UPGRADE here");
18559         }
18560
18561         return intent;
18562     }
18563
18564     public final int broadcastIntent(IApplicationThread caller,
18565             Intent intent, String resolvedType, IIntentReceiver resultTo,
18566             int resultCode, String resultData, Bundle resultExtras,
18567             String[] requiredPermissions, int appOp, Bundle bOptions,
18568             boolean serialized, boolean sticky, int userId) {
18569         enforceNotIsolatedCaller("broadcastIntent");
18570         synchronized(this) {
18571             intent = verifyBroadcastLocked(intent);
18572
18573             final ProcessRecord callerApp = getRecordForAppLocked(caller);
18574             final int callingPid = Binder.getCallingPid();
18575             final int callingUid = Binder.getCallingUid();
18576             final long origId = Binder.clearCallingIdentity();
18577             int res = broadcastIntentLocked(callerApp,
18578                     callerApp != null ? callerApp.info.packageName : null,
18579                     intent, resolvedType, resultTo, resultCode, resultData, resultExtras,
18580                     requiredPermissions, appOp, bOptions, serialized, sticky,
18581                     callingPid, callingUid, userId);
18582             Binder.restoreCallingIdentity(origId);
18583             return res;
18584         }
18585     }
18586
18587
18588     int broadcastIntentInPackage(String packageName, int uid,
18589             Intent intent, String resolvedType, IIntentReceiver resultTo,
18590             int resultCode, String resultData, Bundle resultExtras,
18591             String requiredPermission, Bundle bOptions, boolean serialized, boolean sticky,
18592             int userId) {
18593         synchronized(this) {
18594             intent = verifyBroadcastLocked(intent);
18595
18596             final long origId = Binder.clearCallingIdentity();
18597             String[] requiredPermissions = requiredPermission == null ? null
18598                     : new String[] {requiredPermission};
18599             int res = broadcastIntentLocked(null, packageName, intent, resolvedType,
18600                     resultTo, resultCode, resultData, resultExtras,
18601                     requiredPermissions, AppOpsManager.OP_NONE, bOptions, serialized,
18602                     sticky, -1, uid, userId);
18603             Binder.restoreCallingIdentity(origId);
18604             return res;
18605         }
18606     }
18607
18608     public final void unbroadcastIntent(IApplicationThread caller, Intent intent, int userId) {
18609         // Refuse possible leaked file descriptors
18610         if (intent != null && intent.hasFileDescriptors() == true) {
18611             throw new IllegalArgumentException("File descriptors passed in Intent");
18612         }
18613
18614         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18615                 userId, true, ALLOW_NON_FULL, "removeStickyBroadcast", null);
18616
18617         synchronized(this) {
18618             if (checkCallingPermission(android.Manifest.permission.BROADCAST_STICKY)
18619                     != PackageManager.PERMISSION_GRANTED) {
18620                 String msg = "Permission Denial: unbroadcastIntent() from pid="
18621                         + Binder.getCallingPid()
18622                         + ", uid=" + Binder.getCallingUid()
18623                         + " requires " + android.Manifest.permission.BROADCAST_STICKY;
18624                 Slog.w(TAG, msg);
18625                 throw new SecurityException(msg);
18626             }
18627             ArrayMap<String, ArrayList<Intent>> stickies = mStickyBroadcasts.get(userId);
18628             if (stickies != null) {
18629                 ArrayList<Intent> list = stickies.get(intent.getAction());
18630                 if (list != null) {
18631                     int N = list.size();
18632                     int i;
18633                     for (i=0; i<N; i++) {
18634                         if (intent.filterEquals(list.get(i))) {
18635                             list.remove(i);
18636                             break;
18637                         }
18638                     }
18639                     if (list.size() <= 0) {
18640                         stickies.remove(intent.getAction());
18641                     }
18642                 }
18643                 if (stickies.size() <= 0) {
18644                     mStickyBroadcasts.remove(userId);
18645                 }
18646             }
18647         }
18648     }
18649
18650     void backgroundServicesFinishedLocked(int userId) {
18651         for (BroadcastQueue queue : mBroadcastQueues) {
18652             queue.backgroundServicesFinishedLocked(userId);
18653         }
18654     }
18655
18656     public void finishReceiver(IBinder who, int resultCode, String resultData,
18657             Bundle resultExtras, boolean resultAbort, int flags) {
18658         if (DEBUG_BROADCAST) Slog.v(TAG_BROADCAST, "Finish receiver: " + who);
18659
18660         // Refuse possible leaked file descriptors
18661         if (resultExtras != null && resultExtras.hasFileDescriptors()) {
18662             throw new IllegalArgumentException("File descriptors passed in Bundle");
18663         }
18664
18665         final long origId = Binder.clearCallingIdentity();
18666         try {
18667             boolean doNext = false;
18668             BroadcastRecord r;
18669
18670             synchronized(this) {
18671                 BroadcastQueue queue = (flags & Intent.FLAG_RECEIVER_FOREGROUND) != 0
18672                         ? mFgBroadcastQueue : mBgBroadcastQueue;
18673                 r = queue.getMatchingOrderedReceiver(who);
18674                 if (r != null) {
18675                     doNext = r.queue.finishReceiverLocked(r, resultCode,
18676                         resultData, resultExtras, resultAbort, true);
18677                 }
18678             }
18679
18680             if (doNext) {
18681                 r.queue.processNextBroadcast(false);
18682             }
18683             trimApplications();
18684         } finally {
18685             Binder.restoreCallingIdentity(origId);
18686         }
18687     }
18688
18689     // =========================================================
18690     // INSTRUMENTATION
18691     // =========================================================
18692
18693     public boolean startInstrumentation(ComponentName className,
18694             String profileFile, int flags, Bundle arguments,
18695             IInstrumentationWatcher watcher, IUiAutomationConnection uiAutomationConnection,
18696             int userId, String abiOverride) {
18697         enforceNotIsolatedCaller("startInstrumentation");
18698         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
18699                 userId, false, ALLOW_FULL_ONLY, "startInstrumentation", null);
18700         // Refuse possible leaked file descriptors
18701         if (arguments != null && arguments.hasFileDescriptors()) {
18702             throw new IllegalArgumentException("File descriptors passed in Bundle");
18703         }
18704
18705         synchronized(this) {
18706             InstrumentationInfo ii = null;
18707             ApplicationInfo ai = null;
18708             try {
18709                 ii = mContext.getPackageManager().getInstrumentationInfo(
18710                     className, STOCK_PM_FLAGS);
18711                 ai = AppGlobals.getPackageManager().getApplicationInfo(
18712                         ii.targetPackage, STOCK_PM_FLAGS, userId);
18713             } catch (PackageManager.NameNotFoundException e) {
18714             } catch (RemoteException e) {
18715             }
18716             if (ii == null) {
18717                 reportStartInstrumentationFailureLocked(watcher, className,
18718                         "Unable to find instrumentation info for: " + className);
18719                 return false;
18720             }
18721             if (ai == null) {
18722                 reportStartInstrumentationFailureLocked(watcher, className,
18723                         "Unable to find instrumentation target package: " + ii.targetPackage);
18724                 return false;
18725             }
18726             if (!ai.hasCode()) {
18727                 reportStartInstrumentationFailureLocked(watcher, className,
18728                         "Instrumentation target has no code: " + ii.targetPackage);
18729                 return false;
18730             }
18731
18732             int match = mContext.getPackageManager().checkSignatures(
18733                     ii.targetPackage, ii.packageName);
18734             if (match < 0 && match != PackageManager.SIGNATURE_FIRST_NOT_SIGNED) {
18735                 String msg = "Permission Denial: starting instrumentation "
18736                         + className + " from pid="
18737                         + Binder.getCallingPid()
18738                         + ", uid=" + Binder.getCallingPid()
18739                         + " not allowed because package " + ii.packageName
18740                         + " does not have a signature matching the target "
18741                         + ii.targetPackage;
18742                 reportStartInstrumentationFailureLocked(watcher, className, msg);
18743                 throw new SecurityException(msg);
18744             }
18745
18746             final long origId = Binder.clearCallingIdentity();
18747             // Instrumentation can kill and relaunch even persistent processes
18748             forceStopPackageLocked(ii.targetPackage, -1, true, false, true, true, false, userId,
18749                     "start instr");
18750             ProcessRecord app = addAppLocked(ai, false, abiOverride);
18751             app.instrumentationClass = className;
18752             app.instrumentationInfo = ai;
18753             app.instrumentationProfileFile = profileFile;
18754             app.instrumentationArguments = arguments;
18755             app.instrumentationWatcher = watcher;
18756             app.instrumentationUiAutomationConnection = uiAutomationConnection;
18757             app.instrumentationResultClass = className;
18758             Binder.restoreCallingIdentity(origId);
18759         }
18760
18761         return true;
18762     }
18763
18764     /**
18765      * Report errors that occur while attempting to start Instrumentation.  Always writes the
18766      * error to the logs, but if somebody is watching, send the report there too.  This enables
18767      * the "am" command to report errors with more information.
18768      *
18769      * @param watcher The IInstrumentationWatcher.  Null if there isn't one.
18770      * @param cn The component name of the instrumentation.
18771      * @param report The error report.
18772      */
18773     private void reportStartInstrumentationFailureLocked(IInstrumentationWatcher watcher,
18774             ComponentName cn, String report) {
18775         Slog.w(TAG, report);
18776         if (watcher != null) {
18777             Bundle results = new Bundle();
18778             results.putString(Instrumentation.REPORT_KEY_IDENTIFIER, "ActivityManagerService");
18779             results.putString("Error", report);
18780             mInstrumentationReporter.reportStatus(watcher, cn, -1, results);
18781         }
18782     }
18783
18784     void finishInstrumentationLocked(ProcessRecord app, int resultCode, Bundle results) {
18785         if (app.instrumentationWatcher != null) {
18786             mInstrumentationReporter.reportFinished(app.instrumentationWatcher,
18787                     app.instrumentationClass, resultCode, results);
18788         }
18789
18790         // Can't call out of the system process with a lock held, so post a message.
18791         if (app.instrumentationUiAutomationConnection != null) {
18792             mHandler.obtainMessage(SHUTDOWN_UI_AUTOMATION_CONNECTION_MSG,
18793                     app.instrumentationUiAutomationConnection).sendToTarget();
18794         }
18795
18796         app.instrumentationWatcher = null;
18797         app.instrumentationUiAutomationConnection = null;
18798         app.instrumentationClass = null;
18799         app.instrumentationInfo = null;
18800         app.instrumentationProfileFile = null;
18801         app.instrumentationArguments = null;
18802
18803         forceStopPackageLocked(app.info.packageName, -1, false, false, true, true, false, app.userId,
18804                 "finished inst");
18805     }
18806
18807     public void finishInstrumentation(IApplicationThread target,
18808             int resultCode, Bundle results) {
18809         int userId = UserHandle.getCallingUserId();
18810         // Refuse possible leaked file descriptors
18811         if (results != null && results.hasFileDescriptors()) {
18812             throw new IllegalArgumentException("File descriptors passed in Intent");
18813         }
18814
18815         synchronized(this) {
18816             ProcessRecord app = getRecordForAppLocked(target);
18817             if (app == null) {
18818                 Slog.w(TAG, "finishInstrumentation: no app for " + target);
18819                 return;
18820             }
18821             final long origId = Binder.clearCallingIdentity();
18822             finishInstrumentationLocked(app, resultCode, results);
18823             Binder.restoreCallingIdentity(origId);
18824         }
18825     }
18826
18827     // =========================================================
18828     // CONFIGURATION
18829     // =========================================================
18830
18831     public ConfigurationInfo getDeviceConfigurationInfo() {
18832         ConfigurationInfo config = new ConfigurationInfo();
18833         synchronized (this) {
18834             config.reqTouchScreen = mConfiguration.touchscreen;
18835             config.reqKeyboardType = mConfiguration.keyboard;
18836             config.reqNavigation = mConfiguration.navigation;
18837             if (mConfiguration.navigation == Configuration.NAVIGATION_DPAD
18838                     || mConfiguration.navigation == Configuration.NAVIGATION_TRACKBALL) {
18839                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_FIVE_WAY_NAV;
18840             }
18841             if (mConfiguration.keyboard != Configuration.KEYBOARD_UNDEFINED
18842                     && mConfiguration.keyboard != Configuration.KEYBOARD_NOKEYS) {
18843                 config.reqInputFeatures |= ConfigurationInfo.INPUT_FEATURE_HARD_KEYBOARD;
18844             }
18845             config.reqGlEsVersion = GL_ES_VERSION;
18846         }
18847         return config;
18848     }
18849
18850     ActivityStack getFocusedStack() {
18851         return mStackSupervisor.getFocusedStack();
18852     }
18853
18854     @Override
18855     public int getFocusedStackId() throws RemoteException {
18856         ActivityStack focusedStack = getFocusedStack();
18857         if (focusedStack != null) {
18858             return focusedStack.getStackId();
18859         }
18860         return -1;
18861     }
18862
18863     public Configuration getConfiguration() {
18864         Configuration ci;
18865         synchronized(this) {
18866             ci = new Configuration(mConfiguration);
18867             ci.userSetLocale = false;
18868         }
18869         return ci;
18870     }
18871
18872     @Override
18873     public void suppressResizeConfigChanges(boolean suppress) throws RemoteException {
18874         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "suppressResizeConfigChanges()");
18875         synchronized (this) {
18876             mSuppressResizeConfigChanges = suppress;
18877         }
18878     }
18879
18880     @Override
18881     public void moveTasksToFullscreenStack(int fromStackId, boolean onTop) {
18882         enforceCallingPermission(MANAGE_ACTIVITY_STACKS, "moveTasksToFullscreenStack()");
18883         if (fromStackId == HOME_STACK_ID) {
18884             throw new IllegalArgumentException("You can't move tasks from the home stack.");
18885         }
18886         synchronized (this) {
18887             final long origId = Binder.clearCallingIdentity();
18888             try {
18889                 mStackSupervisor.moveTasksToFullscreenStackLocked(fromStackId, onTop);
18890             } finally {
18891                 Binder.restoreCallingIdentity(origId);
18892             }
18893         }
18894     }
18895
18896     @Override
18897     public void updatePersistentConfiguration(Configuration values) {
18898         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18899                 "updateConfiguration()");
18900         enforceWriteSettingsPermission("updateConfiguration()");
18901         if (values == null) {
18902             throw new NullPointerException("Configuration must not be null");
18903         }
18904
18905         int userId = UserHandle.getCallingUserId();
18906
18907         synchronized(this) {
18908             updatePersistentConfigurationLocked(values, userId);
18909         }
18910     }
18911
18912     private void updatePersistentConfigurationLocked(Configuration values, @UserIdInt int userId) {
18913         final long origId = Binder.clearCallingIdentity();
18914         try {
18915             updateConfigurationLocked(values, null, false, true, userId, false /* deferResume */);
18916         } finally {
18917             Binder.restoreCallingIdentity(origId);
18918         }
18919     }
18920
18921     private void updateFontScaleIfNeeded(@UserIdInt int userId) {
18922         final float scaleFactor = Settings.System.getFloatForUser(mContext.getContentResolver(),
18923                 FONT_SCALE, 1.0f, userId);
18924         if (mConfiguration.fontScale != scaleFactor) {
18925             final Configuration configuration = mWindowManager.computeNewConfiguration();
18926             configuration.fontScale = scaleFactor;
18927             synchronized (this) {
18928                 updatePersistentConfigurationLocked(configuration, userId);
18929             }
18930         }
18931     }
18932
18933     private void enforceWriteSettingsPermission(String func) {
18934         int uid = Binder.getCallingUid();
18935         if (uid == Process.ROOT_UID) {
18936             return;
18937         }
18938
18939         if (Settings.checkAndNoteWriteSettingsOperation(mContext, uid,
18940                 Settings.getPackageNameForUid(mContext, uid), false)) {
18941             return;
18942         }
18943
18944         String msg = "Permission Denial: " + func + " from pid="
18945                 + Binder.getCallingPid()
18946                 + ", uid=" + uid
18947                 + " requires " + android.Manifest.permission.WRITE_SETTINGS;
18948         Slog.w(TAG, msg);
18949         throw new SecurityException(msg);
18950     }
18951
18952     public void updateConfiguration(Configuration values) {
18953         enforceCallingPermission(android.Manifest.permission.CHANGE_CONFIGURATION,
18954                 "updateConfiguration()");
18955
18956         synchronized(this) {
18957             if (values == null && mWindowManager != null) {
18958                 // sentinel: fetch the current configuration from the window manager
18959                 values = mWindowManager.computeNewConfiguration();
18960             }
18961
18962             if (mWindowManager != null) {
18963                 mProcessList.applyDisplaySize(mWindowManager);
18964             }
18965
18966             final long origId = Binder.clearCallingIdentity();
18967             if (values != null) {
18968                 Settings.System.clearConfiguration(values);
18969             }
18970             updateConfigurationLocked(values, null, false);
18971             Binder.restoreCallingIdentity(origId);
18972         }
18973     }
18974
18975     void updateUserConfigurationLocked() {
18976         Configuration configuration = new Configuration(mConfiguration);
18977         Settings.System.adjustConfigurationForUser(mContext.getContentResolver(), configuration,
18978                 mUserController.getCurrentUserIdLocked(), Settings.System.canWrite(mContext));
18979         updateConfigurationLocked(configuration, null, false);
18980     }
18981
18982     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18983             boolean initLocale) {
18984         return updateConfigurationLocked(values, starting, initLocale, false /* deferResume */);
18985     }
18986
18987     boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
18988             boolean initLocale, boolean deferResume) {
18989         // pass UserHandle.USER_NULL as userId because we don't persist configuration for any user
18990         return updateConfigurationLocked(values, starting, initLocale, false /* persistent */,
18991                 UserHandle.USER_NULL, deferResume);
18992     }
18993
18994     // To cache the list of supported system locales
18995     private String[] mSupportedSystemLocales = null;
18996
18997     /**
18998      * Do either or both things: (1) change the current configuration, and (2)
18999      * make sure the given activity is running with the (now) current
19000      * configuration.  Returns true if the activity has been left running, or
19001      * false if <var>starting</var> is being destroyed to match the new
19002      * configuration.
19003      *
19004      * @param userId is only used when persistent parameter is set to true to persist configuration
19005      *               for that particular user
19006      */
19007     private boolean updateConfigurationLocked(Configuration values, ActivityRecord starting,
19008             boolean initLocale, boolean persistent, int userId, boolean deferResume) {
19009         int changes = 0;
19010
19011         if (mWindowManager != null) {
19012             mWindowManager.deferSurfaceLayout();
19013         }
19014         if (values != null) {
19015             Configuration newConfig = new Configuration(mConfiguration);
19016             changes = newConfig.updateFrom(values);
19017             if (changes != 0) {
19018                 if (DEBUG_SWITCH || DEBUG_CONFIGURATION) Slog.i(TAG_CONFIGURATION,
19019                         "Updating configuration to: " + values);
19020
19021                 EventLog.writeEvent(EventLogTags.CONFIGURATION_CHANGED, changes);
19022
19023                 if (!initLocale && !values.getLocales().isEmpty() && values.userSetLocale) {
19024                     final LocaleList locales = values.getLocales();
19025                     int bestLocaleIndex = 0;
19026                     if (locales.size() > 1) {
19027                         if (mSupportedSystemLocales == null) {
19028                             mSupportedSystemLocales =
19029                                     Resources.getSystem().getAssets().getLocales();
19030                         }
19031                         bestLocaleIndex = Math.max(0,
19032                                 locales.getFirstMatchIndex(mSupportedSystemLocales));
19033                     }
19034                     SystemProperties.set("persist.sys.locale",
19035                             locales.get(bestLocaleIndex).toLanguageTag());
19036                     LocaleList.setDefault(locales, bestLocaleIndex);
19037                     mHandler.sendMessage(mHandler.obtainMessage(SEND_LOCALE_TO_MOUNT_DAEMON_MSG,
19038                             locales.get(bestLocaleIndex)));
19039                 }
19040
19041                 mConfigurationSeq++;
19042                 if (mConfigurationSeq <= 0) {
19043                     mConfigurationSeq = 1;
19044                 }
19045                 newConfig.seq = mConfigurationSeq;
19046                 mConfiguration = newConfig;
19047                 Slog.i(TAG, "Config changes=" + Integer.toHexString(changes) + " " + newConfig);
19048                 mUsageStatsService.reportConfigurationChange(newConfig,
19049                         mUserController.getCurrentUserIdLocked());
19050                 //mUsageStatsService.noteStartConfig(newConfig);
19051
19052                 final Configuration configCopy = new Configuration(mConfiguration);
19053
19054                 // TODO: If our config changes, should we auto dismiss any currently
19055                 // showing dialogs?
19056                 mShowDialogs = shouldShowDialogs(newConfig, mInVrMode);
19057
19058                 AttributeCache ac = AttributeCache.instance();
19059                 if (ac != null) {
19060                     ac.updateConfiguration(configCopy);
19061                 }
19062
19063                 // Make sure all resources in our process are updated
19064                 // right now, so that anyone who is going to retrieve
19065                 // resource values after we return will be sure to get
19066                 // the new ones.  This is especially important during
19067                 // boot, where the first config change needs to guarantee
19068                 // all resources have that config before following boot
19069                 // code is executed.
19070                 mSystemThread.applyConfigurationToResources(configCopy);
19071
19072                 if (persistent && Settings.System.hasInterestingConfigurationChanges(changes)) {
19073                     Message msg = mHandler.obtainMessage(UPDATE_CONFIGURATION_MSG);
19074                     msg.obj = new Configuration(configCopy);
19075                     msg.arg1 = userId;
19076                     mHandler.sendMessage(msg);
19077                 }
19078
19079                 final boolean isDensityChange = (changes & ActivityInfo.CONFIG_DENSITY) != 0;
19080                 if (isDensityChange) {
19081                     // Reset the unsupported display size dialog.
19082                     mUiHandler.sendEmptyMessage(SHOW_UNSUPPORTED_DISPLAY_SIZE_DIALOG_MSG);
19083
19084                     killAllBackgroundProcessesExcept(Build.VERSION_CODES.N,
19085                             ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE);
19086                 }
19087
19088                 for (int i=mLruProcesses.size()-1; i>=0; i--) {
19089                     ProcessRecord app = mLruProcesses.get(i);
19090                     try {
19091                         if (app.thread != null) {
19092                             if (DEBUG_CONFIGURATION) Slog.v(TAG_CONFIGURATION, "Sending to proc "
19093                                     + app.processName + " new config " + mConfiguration);
19094                             app.thread.scheduleConfigurationChanged(configCopy);
19095                         }
19096                     } catch (Exception e) {
19097                     }
19098                 }
19099                 Intent intent = new Intent(Intent.ACTION_CONFIGURATION_CHANGED);
19100                 intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY
19101                         | Intent.FLAG_RECEIVER_REPLACE_PENDING
19102                         | Intent.FLAG_RECEIVER_FOREGROUND);
19103                 broadcastIntentLocked(null, null, intent, null, null, 0, null, null,
19104                         null, AppOpsManager.OP_NONE, null, false, false,
19105                         MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19106                 if ((changes&ActivityInfo.CONFIG_LOCALE) != 0) {
19107                     intent = new Intent(Intent.ACTION_LOCALE_CHANGED);
19108                     intent.addFlags(Intent.FLAG_RECEIVER_FOREGROUND);
19109                     if (initLocale || !mProcessesReady) {
19110                         intent.addFlags(Intent.FLAG_RECEIVER_REGISTERED_ONLY);
19111                     }
19112                     broadcastIntentLocked(null, null, intent,
19113                             null, null, 0, null, null, null, AppOpsManager.OP_NONE,
19114                             null, false, false, MY_PID, Process.SYSTEM_UID, UserHandle.USER_ALL);
19115                 }
19116             }
19117             // Update the configuration with WM first and check if any of the stacks need to be
19118             // resized due to the configuration change. If so, resize the stacks now and do any
19119             // relaunches if necessary. This way we don't need to relaunch again below in
19120             // ensureActivityConfigurationLocked().
19121             if (mWindowManager != null) {
19122                 final int[] resizedStacks = mWindowManager.setNewConfiguration(mConfiguration);
19123                 if (resizedStacks != null) {
19124                     for (int stackId : resizedStacks) {
19125                         final Rect newBounds = mWindowManager.getBoundsForNewConfiguration(stackId);
19126                         mStackSupervisor.resizeStackLocked(
19127                                 stackId, newBounds, null, null, false, false, deferResume);
19128                     }
19129                 }
19130             }
19131         }
19132
19133         boolean kept = true;
19134         final ActivityStack mainStack = mStackSupervisor.getFocusedStack();
19135         // mainStack is null during startup.
19136         if (mainStack != null) {
19137             if (changes != 0 && starting == null) {
19138                 // If the configuration changed, and the caller is not already
19139                 // in the process of starting an activity, then find the top
19140                 // activity to check if its configuration needs to change.
19141                 starting = mainStack.topRunningActivityLocked();
19142             }
19143
19144             if (starting != null) {
19145                 kept = mainStack.ensureActivityConfigurationLocked(starting, changes, false);
19146                 // And we need to make sure at this point that all other activities
19147                 // are made visible with the correct configuration.
19148                 mStackSupervisor.ensureActivitiesVisibleLocked(starting, changes,
19149                         !PRESERVE_WINDOWS);
19150             }
19151         }
19152         if (mWindowManager != null) {
19153             mWindowManager.continueSurfaceLayout();
19154         }
19155         return kept;
19156     }
19157
19158     /**
19159      * Decide based on the configuration whether we should shouw the ANR,
19160      * crash, etc dialogs.  The idea is that if there is no affordence to
19161      * press the on-screen buttons, or the user experience would be more
19162      * greatly impacted than the crash itself, we shouldn't show the dialog.
19163      *
19164      * A thought: SystemUI might also want to get told about this, the Power
19165      * dialog / global actions also might want different behaviors.
19166      */
19167     private static final boolean shouldShowDialogs(Configuration config, boolean inVrMode) {
19168         final boolean inputMethodExists = !(config.keyboard == Configuration.KEYBOARD_NOKEYS
19169                                    && config.touchscreen == Configuration.TOUCHSCREEN_NOTOUCH
19170                                    && config.navigation == Configuration.NAVIGATION_NONAV);
19171         int modeType = config.uiMode & Configuration.UI_MODE_TYPE_MASK;
19172         final boolean uiModeSupportsDialogs = (modeType != Configuration.UI_MODE_TYPE_CAR
19173                 && !(modeType == Configuration.UI_MODE_TYPE_WATCH && "user".equals(Build.TYPE)));
19174         return inputMethodExists && uiModeSupportsDialogs && !inVrMode;
19175     }
19176
19177     @Override
19178     public boolean shouldUpRecreateTask(IBinder token, String destAffinity) {
19179         synchronized (this) {
19180             ActivityRecord srec = ActivityRecord.forTokenLocked(token);
19181             if (srec != null) {
19182                 return srec.task.stack.shouldUpRecreateTaskLocked(srec, destAffinity);
19183             }
19184         }
19185         return false;
19186     }
19187
19188     public boolean navigateUpTo(IBinder token, Intent destIntent, int resultCode,
19189             Intent resultData) {
19190
19191         synchronized (this) {
19192             final ActivityRecord r = ActivityRecord.forTokenLocked(token);
19193             if (r != null) {
19194                 return r.task.stack.navigateUpToLocked(r, destIntent, resultCode, resultData);
19195             }
19196             return false;
19197         }
19198     }
19199
19200     public int getLaunchedFromUid(IBinder activityToken) {
19201         ActivityRecord srec;
19202         synchronized (this) {
19203             srec = ActivityRecord.forTokenLocked(activityToken);
19204         }
19205         if (srec == null) {
19206             return -1;
19207         }
19208         return srec.launchedFromUid;
19209     }
19210
19211     public String getLaunchedFromPackage(IBinder activityToken) {
19212         ActivityRecord srec;
19213         synchronized (this) {
19214             srec = ActivityRecord.forTokenLocked(activityToken);
19215         }
19216         if (srec == null) {
19217             return null;
19218         }
19219         return srec.launchedFromPackage;
19220     }
19221
19222     // =========================================================
19223     // LIFETIME MANAGEMENT
19224     // =========================================================
19225
19226     // Returns which broadcast queue the app is the current [or imminent] receiver
19227     // on, or 'null' if the app is not an active broadcast recipient.
19228     private BroadcastQueue isReceivingBroadcast(ProcessRecord app) {
19229         BroadcastRecord r = app.curReceiver;
19230         if (r != null) {
19231             return r.queue;
19232         }
19233
19234         // It's not the current receiver, but it might be starting up to become one
19235         synchronized (this) {
19236             for (BroadcastQueue queue : mBroadcastQueues) {
19237                 r = queue.mPendingBroadcast;
19238                 if (r != null && r.curApp == app) {
19239                     // found it; report which queue it's in
19240                     return queue;
19241                 }
19242             }
19243         }
19244
19245         return null;
19246     }
19247
19248     Association startAssociationLocked(int sourceUid, String sourceProcess, int sourceState,
19249             int targetUid, ComponentName targetComponent, String targetProcess) {
19250         if (!mTrackingAssociations) {
19251             return null;
19252         }
19253         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19254                 = mAssociations.get(targetUid);
19255         if (components == null) {
19256             components = new ArrayMap<>();
19257             mAssociations.put(targetUid, components);
19258         }
19259         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19260         if (sourceUids == null) {
19261             sourceUids = new SparseArray<>();
19262             components.put(targetComponent, sourceUids);
19263         }
19264         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19265         if (sourceProcesses == null) {
19266             sourceProcesses = new ArrayMap<>();
19267             sourceUids.put(sourceUid, sourceProcesses);
19268         }
19269         Association ass = sourceProcesses.get(sourceProcess);
19270         if (ass == null) {
19271             ass = new Association(sourceUid, sourceProcess, targetUid, targetComponent,
19272                     targetProcess);
19273             sourceProcesses.put(sourceProcess, ass);
19274         }
19275         ass.mCount++;
19276         ass.mNesting++;
19277         if (ass.mNesting == 1) {
19278             ass.mStartTime = ass.mLastStateUptime = SystemClock.uptimeMillis();
19279             ass.mLastState = sourceState;
19280         }
19281         return ass;
19282     }
19283
19284     void stopAssociationLocked(int sourceUid, String sourceProcess, int targetUid,
19285             ComponentName targetComponent) {
19286         if (!mTrackingAssociations) {
19287             return;
19288         }
19289         ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> components
19290                 = mAssociations.get(targetUid);
19291         if (components == null) {
19292             return;
19293         }
19294         SparseArray<ArrayMap<String, Association>> sourceUids = components.get(targetComponent);
19295         if (sourceUids == null) {
19296             return;
19297         }
19298         ArrayMap<String, Association> sourceProcesses = sourceUids.get(sourceUid);
19299         if (sourceProcesses == null) {
19300             return;
19301         }
19302         Association ass = sourceProcesses.get(sourceProcess);
19303         if (ass == null || ass.mNesting <= 0) {
19304             return;
19305         }
19306         ass.mNesting--;
19307         if (ass.mNesting == 0) {
19308             long uptime = SystemClock.uptimeMillis();
19309             ass.mTime += uptime - ass.mStartTime;
19310             ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19311                     += uptime - ass.mLastStateUptime;
19312             ass.mLastState = ActivityManager.MAX_PROCESS_STATE + 2;
19313         }
19314     }
19315
19316     private void noteUidProcessState(final int uid, final int state) {
19317         mBatteryStatsService.noteUidProcessState(uid, state);
19318         if (mTrackingAssociations) {
19319             for (int i1=0, N1=mAssociations.size(); i1<N1; i1++) {
19320                 ArrayMap<ComponentName, SparseArray<ArrayMap<String, Association>>> targetComponents
19321                         = mAssociations.valueAt(i1);
19322                 for (int i2=0, N2=targetComponents.size(); i2<N2; i2++) {
19323                     SparseArray<ArrayMap<String, Association>> sourceUids
19324                             = targetComponents.valueAt(i2);
19325                     ArrayMap<String, Association> sourceProcesses = sourceUids.get(uid);
19326                     if (sourceProcesses != null) {
19327                         for (int i4=0, N4=sourceProcesses.size(); i4<N4; i4++) {
19328                             Association ass = sourceProcesses.valueAt(i4);
19329                             if (ass.mNesting >= 1) {
19330                                 // currently associated
19331                                 long uptime = SystemClock.uptimeMillis();
19332                                 ass.mStateTimes[ass.mLastState-ActivityManager.MIN_PROCESS_STATE]
19333                                         += uptime - ass.mLastStateUptime;
19334                                 ass.mLastState = state;
19335                                 ass.mLastStateUptime = uptime;
19336                             }
19337                         }
19338                     }
19339                 }
19340             }
19341         }
19342     }
19343
19344     private final int computeOomAdjLocked(ProcessRecord app, int cachedAdj, ProcessRecord TOP_APP,
19345             boolean doingAll, long now) {
19346         if (mAdjSeq == app.adjSeq) {
19347             // This adjustment has already been computed.
19348             return app.curRawAdj;
19349         }
19350
19351         if (app.thread == null) {
19352             app.adjSeq = mAdjSeq;
19353             app.curSchedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19354             app.curProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19355             return (app.curAdj=app.curRawAdj=ProcessList.CACHED_APP_MAX_ADJ);
19356         }
19357
19358         app.adjTypeCode = ActivityManager.RunningAppProcessInfo.REASON_UNKNOWN;
19359         app.adjSource = null;
19360         app.adjTarget = null;
19361         app.empty = false;
19362         app.cached = false;
19363
19364         final int activitiesSize = app.activities.size();
19365
19366         if (app.maxAdj <= ProcessList.FOREGROUND_APP_ADJ) {
19367             // The max adjustment doesn't allow this app to be anything
19368             // below foreground, so it is not worth doing work for it.
19369             app.adjType = "fixed";
19370             app.adjSeq = mAdjSeq;
19371             app.curRawAdj = app.maxAdj;
19372             app.foregroundActivities = false;
19373             app.curSchedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19374             app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT;
19375             // System processes can do UI, and when they do we want to have
19376             // them trim their memory after the user leaves the UI.  To
19377             // facilitate this, here we need to determine whether or not it
19378             // is currently showing UI.
19379             app.systemNoUi = true;
19380             if (app == TOP_APP) {
19381                 app.systemNoUi = false;
19382                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19383                 app.adjType = "pers-top-activity";
19384             } else if (app.hasTopUi) {
19385                 app.systemNoUi = false;
19386                 app.curSchedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19387                 app.adjType = "pers-top-ui";
19388             } else if (activitiesSize > 0) {
19389                 for (int j = 0; j < activitiesSize; j++) {
19390                     final ActivityRecord r = app.activities.get(j);
19391                     if (r.visible) {
19392                         app.systemNoUi = false;
19393                     }
19394                 }
19395             }
19396             if (!app.systemNoUi) {
19397                 app.curProcState = ActivityManager.PROCESS_STATE_PERSISTENT_UI;
19398             }
19399             return (app.curAdj=app.maxAdj);
19400         }
19401
19402         app.systemNoUi = false;
19403
19404         final int PROCESS_STATE_CUR_TOP = mTopProcessState;
19405
19406         // Determine the importance of the process, starting with most
19407         // important to least, and assign an appropriate OOM adjustment.
19408         int adj;
19409         int schedGroup;
19410         int procState;
19411         boolean foregroundActivities = false;
19412         BroadcastQueue queue;
19413         if (app == TOP_APP) {
19414             // The last app on the list is the foreground app.
19415             adj = ProcessList.FOREGROUND_APP_ADJ;
19416             schedGroup = ProcessList.SCHED_GROUP_TOP_APP;
19417             app.adjType = "top-activity";
19418             foregroundActivities = true;
19419             procState = PROCESS_STATE_CUR_TOP;
19420         } else if (app.instrumentationClass != null) {
19421             // Don't want to kill running instrumentation.
19422             adj = ProcessList.FOREGROUND_APP_ADJ;
19423             schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19424             app.adjType = "instrumentation";
19425             procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19426         } else if ((queue = isReceivingBroadcast(app)) != null) {
19427             // An app that is currently receiving a broadcast also
19428             // counts as being in the foreground for OOM killer purposes.
19429             // It's placed in a sched group based on the nature of the
19430             // broadcast as reflected by which queue it's active in.
19431             adj = ProcessList.FOREGROUND_APP_ADJ;
19432             schedGroup = (queue == mFgBroadcastQueue)
19433                     ? ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19434             app.adjType = "broadcast";
19435             procState = ActivityManager.PROCESS_STATE_RECEIVER;
19436         } else if (app.executingServices.size() > 0) {
19437             // An app that is currently executing a service callback also
19438             // counts as being in the foreground.
19439             adj = ProcessList.FOREGROUND_APP_ADJ;
19440             schedGroup = app.execServicesFg ?
19441                     ProcessList.SCHED_GROUP_DEFAULT : ProcessList.SCHED_GROUP_BACKGROUND;
19442             app.adjType = "exec-service";
19443             procState = ActivityManager.PROCESS_STATE_SERVICE;
19444             //Slog.i(TAG, "EXEC " + (app.execServicesFg ? "FG" : "BG") + ": " + app);
19445         } else {
19446             // As far as we know the process is empty.  We may change our mind later.
19447             schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19448             // At this point we don't actually know the adjustment.  Use the cached adj
19449             // value that the caller wants us to.
19450             adj = cachedAdj;
19451             procState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19452             app.cached = true;
19453             app.empty = true;
19454             app.adjType = "cch-empty";
19455         }
19456
19457         // Examine all activities if not already foreground.
19458         if (!foregroundActivities && activitiesSize > 0) {
19459             int minLayer = ProcessList.VISIBLE_APP_LAYER_MAX;
19460             for (int j = 0; j < activitiesSize; j++) {
19461                 final ActivityRecord r = app.activities.get(j);
19462                 if (r.app != app) {
19463                     Log.e(TAG, "Found activity " + r + " in proc activity list using " + r.app
19464                             + " instead of expected " + app);
19465                     if (r.app == null || (r.app.uid == app.uid)) {
19466                         // Only fix things up when they look sane
19467                         r.app = app;
19468                     } else {
19469                         continue;
19470                     }
19471                 }
19472                 if (r.visible) {
19473                     // App has a visible activity; only upgrade adjustment.
19474                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19475                         adj = ProcessList.VISIBLE_APP_ADJ;
19476                         app.adjType = "visible";
19477                     }
19478                     if (procState > PROCESS_STATE_CUR_TOP) {
19479                         procState = PROCESS_STATE_CUR_TOP;
19480                     }
19481                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19482                     app.cached = false;
19483                     app.empty = false;
19484                     foregroundActivities = true;
19485                     if (r.task != null && minLayer > 0) {
19486                         final int layer = r.task.mLayerRank;
19487                         if (layer >= 0 && minLayer > layer) {
19488                             minLayer = layer;
19489                         }
19490                     }
19491                     break;
19492                 } else if (r.state == ActivityState.PAUSING || r.state == ActivityState.PAUSED) {
19493                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19494                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19495                         app.adjType = "pausing";
19496                     }
19497                     if (procState > PROCESS_STATE_CUR_TOP) {
19498                         procState = PROCESS_STATE_CUR_TOP;
19499                     }
19500                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19501                     app.cached = false;
19502                     app.empty = false;
19503                     foregroundActivities = true;
19504                 } else if (r.state == ActivityState.STOPPING) {
19505                     if (adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19506                         adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19507                         app.adjType = "stopping";
19508                     }
19509                     // For the process state, we will at this point consider the
19510                     // process to be cached.  It will be cached either as an activity
19511                     // or empty depending on whether the activity is finishing.  We do
19512                     // this so that we can treat the process as cached for purposes of
19513                     // memory trimming (determing current memory level, trim command to
19514                     // send to process) since there can be an arbitrary number of stopping
19515                     // processes and they should soon all go into the cached state.
19516                     if (!r.finishing) {
19517                         if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19518                             procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19519                         }
19520                     }
19521                     app.cached = false;
19522                     app.empty = false;
19523                     foregroundActivities = true;
19524                 } else {
19525                     if (procState > ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19526                         procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19527                         app.adjType = "cch-act";
19528                     }
19529                 }
19530             }
19531             if (adj == ProcessList.VISIBLE_APP_ADJ) {
19532                 adj += minLayer;
19533             }
19534         }
19535
19536         if (adj > ProcessList.PERCEPTIBLE_APP_ADJ
19537                 || procState > ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE) {
19538             if (app.foregroundServices) {
19539                 // The user is aware of this app, so make it visible.
19540                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19541                 procState = ActivityManager.PROCESS_STATE_FOREGROUND_SERVICE;
19542                 app.cached = false;
19543                 app.adjType = "fg-service";
19544                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19545             } else if (app.forcingToForeground != null) {
19546                 // The user is aware of this app, so make it visible.
19547                 adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19548                 procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19549                 app.cached = false;
19550                 app.adjType = "force-fg";
19551                 app.adjSource = app.forcingToForeground;
19552                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19553             }
19554         }
19555
19556         if (app == mHeavyWeightProcess) {
19557             if (adj > ProcessList.HEAVY_WEIGHT_APP_ADJ) {
19558                 // We don't want to kill the current heavy-weight process.
19559                 adj = ProcessList.HEAVY_WEIGHT_APP_ADJ;
19560                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19561                 app.cached = false;
19562                 app.adjType = "heavy";
19563             }
19564             if (procState > ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
19565                 procState = ActivityManager.PROCESS_STATE_HEAVY_WEIGHT;
19566             }
19567         }
19568
19569         if (app == mHomeProcess) {
19570             if (adj > ProcessList.HOME_APP_ADJ) {
19571                 // This process is hosting what we currently consider to be the
19572                 // home app, so we don't want to let it go into the background.
19573                 adj = ProcessList.HOME_APP_ADJ;
19574                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19575                 app.cached = false;
19576                 app.adjType = "home";
19577             }
19578             if (procState > ActivityManager.PROCESS_STATE_HOME) {
19579                 procState = ActivityManager.PROCESS_STATE_HOME;
19580             }
19581         }
19582
19583         if (app == mPreviousProcess && app.activities.size() > 0) {
19584             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19585                 // This was the previous process that showed UI to the user.
19586                 // We want to try to keep it around more aggressively, to give
19587                 // a good experience around switching between two apps.
19588                 adj = ProcessList.PREVIOUS_APP_ADJ;
19589                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19590                 app.cached = false;
19591                 app.adjType = "previous";
19592             }
19593             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19594                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19595             }
19596         }
19597
19598         if (false) Slog.i(TAG, "OOM " + app + ": initial adj=" + adj
19599                 + " reason=" + app.adjType);
19600
19601         // By default, we use the computed adjustment.  It may be changed if
19602         // there are applications dependent on our services or providers, but
19603         // this gives us a baseline and makes sure we don't get into an
19604         // infinite recursion.
19605         app.adjSeq = mAdjSeq;
19606         app.curRawAdj = adj;
19607         app.hasStartedServices = false;
19608
19609         if (mBackupTarget != null && app == mBackupTarget.app) {
19610             // If possible we want to avoid killing apps while they're being backed up
19611             if (adj > ProcessList.BACKUP_APP_ADJ) {
19612                 if (DEBUG_BACKUP) Slog.v(TAG_BACKUP, "oom BACKUP_APP_ADJ for " + app);
19613                 adj = ProcessList.BACKUP_APP_ADJ;
19614                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19615                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19616                 }
19617                 app.adjType = "backup";
19618                 app.cached = false;
19619             }
19620             if (procState > ActivityManager.PROCESS_STATE_BACKUP) {
19621                 procState = ActivityManager.PROCESS_STATE_BACKUP;
19622             }
19623         }
19624
19625         boolean mayBeTop = false;
19626
19627         for (int is = app.services.size()-1;
19628                 is >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19629                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19630                         || procState > ActivityManager.PROCESS_STATE_TOP);
19631                 is--) {
19632             ServiceRecord s = app.services.valueAt(is);
19633             if (s.startRequested) {
19634                 app.hasStartedServices = true;
19635                 if (procState > ActivityManager.PROCESS_STATE_SERVICE) {
19636                     procState = ActivityManager.PROCESS_STATE_SERVICE;
19637                 }
19638                 if (app.hasShownUi && app != mHomeProcess) {
19639                     // If this process has shown some UI, let it immediately
19640                     // go to the LRU list because it may be pretty heavy with
19641                     // UI stuff.  We'll tag it with a label just to help
19642                     // debug and understand what is going on.
19643                     if (adj > ProcessList.SERVICE_ADJ) {
19644                         app.adjType = "cch-started-ui-services";
19645                     }
19646                 } else {
19647                     if (now < (s.lastActivity + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19648                         // This service has seen some activity within
19649                         // recent memory, so we will keep its process ahead
19650                         // of the background processes.
19651                         if (adj > ProcessList.SERVICE_ADJ) {
19652                             adj = ProcessList.SERVICE_ADJ;
19653                             app.adjType = "started-services";
19654                             app.cached = false;
19655                         }
19656                     }
19657                     // If we have let the service slide into the background
19658                     // state, still have some text describing what it is doing
19659                     // even though the service no longer has an impact.
19660                     if (adj > ProcessList.SERVICE_ADJ) {
19661                         app.adjType = "cch-started-services";
19662                     }
19663                 }
19664             }
19665
19666             for (int conni = s.connections.size()-1;
19667                     conni >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19668                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19669                             || procState > ActivityManager.PROCESS_STATE_TOP);
19670                     conni--) {
19671                 ArrayList<ConnectionRecord> clist = s.connections.valueAt(conni);
19672                 for (int i = 0;
19673                         i < clist.size() && (adj > ProcessList.FOREGROUND_APP_ADJ
19674                                 || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19675                                 || procState > ActivityManager.PROCESS_STATE_TOP);
19676                         i++) {
19677                     // XXX should compute this based on the max of
19678                     // all connected clients.
19679                     ConnectionRecord cr = clist.get(i);
19680                     if (cr.binding.client == app) {
19681                         // Binding to ourself is not interesting.
19682                         continue;
19683                     }
19684
19685                     if ((cr.flags&Context.BIND_WAIVE_PRIORITY) == 0) {
19686                         ProcessRecord client = cr.binding.client;
19687                         int clientAdj = computeOomAdjLocked(client, cachedAdj,
19688                                 TOP_APP, doingAll, now);
19689                         int clientProcState = client.curProcState;
19690                         if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19691                             // If the other app is cached for any reason, for purposes here
19692                             // we are going to consider it empty.  The specific cached state
19693                             // doesn't propagate except under certain conditions.
19694                             clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19695                         }
19696                         String adjType = null;
19697                         if ((cr.flags&Context.BIND_ALLOW_OOM_MANAGEMENT) != 0) {
19698                             // Not doing bind OOM management, so treat
19699                             // this guy more like a started service.
19700                             if (app.hasShownUi && app != mHomeProcess) {
19701                                 // If this process has shown some UI, let it immediately
19702                                 // go to the LRU list because it may be pretty heavy with
19703                                 // UI stuff.  We'll tag it with a label just to help
19704                                 // debug and understand what is going on.
19705                                 if (adj > clientAdj) {
19706                                     adjType = "cch-bound-ui-services";
19707                                 }
19708                                 app.cached = false;
19709                                 clientAdj = adj;
19710                                 clientProcState = procState;
19711                             } else {
19712                                 if (now >= (s.lastActivity
19713                                         + ActiveServices.MAX_SERVICE_INACTIVITY)) {
19714                                     // This service has not seen activity within
19715                                     // recent memory, so allow it to drop to the
19716                                     // LRU list if there is no other reason to keep
19717                                     // it around.  We'll also tag it with a label just
19718                                     // to help debug and undertand what is going on.
19719                                     if (adj > clientAdj) {
19720                                         adjType = "cch-bound-services";
19721                                     }
19722                                     clientAdj = adj;
19723                                 }
19724                             }
19725                         }
19726                         if (adj > clientAdj) {
19727                             // If this process has recently shown UI, and
19728                             // the process that is binding to it is less
19729                             // important than being visible, then we don't
19730                             // care about the binding as much as we care
19731                             // about letting this process get into the LRU
19732                             // list to be killed and restarted if needed for
19733                             // memory.
19734                             if (app.hasShownUi && app != mHomeProcess
19735                                     && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19736                                 adjType = "cch-bound-ui-services";
19737                             } else {
19738                                 if ((cr.flags&(Context.BIND_ABOVE_CLIENT
19739                                         |Context.BIND_IMPORTANT)) != 0) {
19740                                     adj = clientAdj >= ProcessList.PERSISTENT_SERVICE_ADJ
19741                                             ? clientAdj : ProcessList.PERSISTENT_SERVICE_ADJ;
19742                                 } else if ((cr.flags&Context.BIND_NOT_VISIBLE) != 0
19743                                         && clientAdj < ProcessList.PERCEPTIBLE_APP_ADJ
19744                                         && adj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19745                                     adj = ProcessList.PERCEPTIBLE_APP_ADJ;
19746                                 } else if (clientAdj >= ProcessList.PERCEPTIBLE_APP_ADJ) {
19747                                     adj = clientAdj;
19748                                 } else {
19749                                     if (adj > ProcessList.VISIBLE_APP_ADJ) {
19750                                         adj = Math.max(clientAdj, ProcessList.VISIBLE_APP_ADJ);
19751                                     }
19752                                 }
19753                                 if (!client.cached) {
19754                                     app.cached = false;
19755                                 }
19756                                 adjType = "service";
19757                             }
19758                         }
19759                         if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19760                             // This will treat important bound services identically to
19761                             // the top app, which may behave differently than generic
19762                             // foreground work.
19763                             if (client.curSchedGroup > schedGroup) {
19764                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19765                                     schedGroup = client.curSchedGroup;
19766                                 } else {
19767                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19768                                 }
19769                             }
19770                             if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19771                                 if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19772                                     // Special handling of clients who are in the top state.
19773                                     // We *may* want to consider this process to be in the
19774                                     // top state as well, but only if there is not another
19775                                     // reason for it to be running.  Being on the top is a
19776                                     // special state, meaning you are specifically running
19777                                     // for the current top app.  If the process is already
19778                                     // running in the background for some other reason, it
19779                                     // is more important to continue considering it to be
19780                                     // in the background state.
19781                                     mayBeTop = true;
19782                                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19783                                 } else {
19784                                     // Special handling for above-top states (persistent
19785                                     // processes).  These should not bring the current process
19786                                     // into the top state, since they are not on top.  Instead
19787                                     // give them the best state after that.
19788                                     if ((cr.flags&Context.BIND_FOREGROUND_SERVICE) != 0) {
19789                                         clientProcState =
19790                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19791                                     } else if (mWakefulness
19792                                                     == PowerManagerInternal.WAKEFULNESS_AWAKE &&
19793                                             (cr.flags&Context.BIND_FOREGROUND_SERVICE_WHILE_AWAKE)
19794                                                     != 0) {
19795                                         clientProcState =
19796                                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19797                                     } else {
19798                                         clientProcState =
19799                                                 ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19800                                     }
19801                                 }
19802                             }
19803                         } else {
19804                             if (clientProcState <
19805                                     ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND) {
19806                                 clientProcState =
19807                                         ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND;
19808                             }
19809                         }
19810                         if (procState > clientProcState) {
19811                             procState = clientProcState;
19812                         }
19813                         if (procState < ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
19814                                 && (cr.flags&Context.BIND_SHOWING_UI) != 0) {
19815                             app.pendingUiClean = true;
19816                         }
19817                         if (adjType != null) {
19818                             app.adjType = adjType;
19819                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19820                                     .REASON_SERVICE_IN_USE;
19821                             app.adjSource = cr.binding.client;
19822                             app.adjSourceProcState = clientProcState;
19823                             app.adjTarget = s.name;
19824                         }
19825                     }
19826                     if ((cr.flags&Context.BIND_TREAT_LIKE_ACTIVITY) != 0) {
19827                         app.treatLikeActivity = true;
19828                     }
19829                     final ActivityRecord a = cr.activity;
19830                     if ((cr.flags&Context.BIND_ADJUST_WITH_ACTIVITY) != 0) {
19831                         if (a != null && adj > ProcessList.FOREGROUND_APP_ADJ &&
19832                             (a.visible || a.state == ActivityState.RESUMED ||
19833                              a.state == ActivityState.PAUSING)) {
19834                             adj = ProcessList.FOREGROUND_APP_ADJ;
19835                             if ((cr.flags&Context.BIND_NOT_FOREGROUND) == 0) {
19836                                 if ((cr.flags&Context.BIND_IMPORTANT) != 0) {
19837                                     schedGroup = ProcessList.SCHED_GROUP_TOP_APP_BOUND;
19838                                 } else {
19839                                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19840                                 }
19841                             }
19842                             app.cached = false;
19843                             app.adjType = "service";
19844                             app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19845                                     .REASON_SERVICE_IN_USE;
19846                             app.adjSource = a;
19847                             app.adjSourceProcState = procState;
19848                             app.adjTarget = s.name;
19849                         }
19850                     }
19851                 }
19852             }
19853         }
19854
19855         for (int provi = app.pubProviders.size()-1;
19856                 provi >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19857                         || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19858                         || procState > ActivityManager.PROCESS_STATE_TOP);
19859                 provi--) {
19860             ContentProviderRecord cpr = app.pubProviders.valueAt(provi);
19861             for (int i = cpr.connections.size()-1;
19862                     i >= 0 && (adj > ProcessList.FOREGROUND_APP_ADJ
19863                             || schedGroup == ProcessList.SCHED_GROUP_BACKGROUND
19864                             || procState > ActivityManager.PROCESS_STATE_TOP);
19865                     i--) {
19866                 ContentProviderConnection conn = cpr.connections.get(i);
19867                 ProcessRecord client = conn.client;
19868                 if (client == app) {
19869                     // Being our own client is not interesting.
19870                     continue;
19871                 }
19872                 int clientAdj = computeOomAdjLocked(client, cachedAdj, TOP_APP, doingAll, now);
19873                 int clientProcState = client.curProcState;
19874                 if (clientProcState >= ActivityManager.PROCESS_STATE_CACHED_ACTIVITY) {
19875                     // If the other app is cached for any reason, for purposes here
19876                     // we are going to consider it empty.
19877                     clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19878                 }
19879                 if (adj > clientAdj) {
19880                     if (app.hasShownUi && app != mHomeProcess
19881                             && clientAdj > ProcessList.PERCEPTIBLE_APP_ADJ) {
19882                         app.adjType = "cch-ui-provider";
19883                     } else {
19884                         adj = clientAdj > ProcessList.FOREGROUND_APP_ADJ
19885                                 ? clientAdj : ProcessList.FOREGROUND_APP_ADJ;
19886                         app.adjType = "provider";
19887                     }
19888                     app.cached &= client.cached;
19889                     app.adjTypeCode = ActivityManager.RunningAppProcessInfo
19890                             .REASON_PROVIDER_IN_USE;
19891                     app.adjSource = client;
19892                     app.adjSourceProcState = clientProcState;
19893                     app.adjTarget = cpr.name;
19894                 }
19895                 if (clientProcState <= ActivityManager.PROCESS_STATE_TOP) {
19896                     if (clientProcState == ActivityManager.PROCESS_STATE_TOP) {
19897                         // Special handling of clients who are in the top state.
19898                         // We *may* want to consider this process to be in the
19899                         // top state as well, but only if there is not another
19900                         // reason for it to be running.  Being on the top is a
19901                         // special state, meaning you are specifically running
19902                         // for the current top app.  If the process is already
19903                         // running in the background for some other reason, it
19904                         // is more important to continue considering it to be
19905                         // in the background state.
19906                         mayBeTop = true;
19907                         clientProcState = ActivityManager.PROCESS_STATE_CACHED_EMPTY;
19908                     } else {
19909                         // Special handling for above-top states (persistent
19910                         // processes).  These should not bring the current process
19911                         // into the top state, since they are not on top.  Instead
19912                         // give them the best state after that.
19913                         clientProcState =
19914                                 ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19915                     }
19916                 }
19917                 if (procState > clientProcState) {
19918                     procState = clientProcState;
19919                 }
19920                 if (client.curSchedGroup > schedGroup) {
19921                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19922                 }
19923             }
19924             // If the provider has external (non-framework) process
19925             // dependencies, ensure that its adjustment is at least
19926             // FOREGROUND_APP_ADJ.
19927             if (cpr.hasExternalProcessHandles()) {
19928                 if (adj > ProcessList.FOREGROUND_APP_ADJ) {
19929                     adj = ProcessList.FOREGROUND_APP_ADJ;
19930                     schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
19931                     app.cached = false;
19932                     app.adjType = "provider";
19933                     app.adjTarget = cpr.name;
19934                 }
19935                 if (procState > ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
19936                     procState = ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
19937                 }
19938             }
19939         }
19940
19941         if (app.lastProviderTime > 0 && (app.lastProviderTime+CONTENT_PROVIDER_RETAIN_TIME) > now) {
19942             if (adj > ProcessList.PREVIOUS_APP_ADJ) {
19943                 adj = ProcessList.PREVIOUS_APP_ADJ;
19944                 schedGroup = ProcessList.SCHED_GROUP_BACKGROUND;
19945                 app.cached = false;
19946                 app.adjType = "provider";
19947             }
19948             if (procState > ActivityManager.PROCESS_STATE_LAST_ACTIVITY) {
19949                 procState = ActivityManager.PROCESS_STATE_LAST_ACTIVITY;
19950             }
19951         }
19952
19953         if (mayBeTop && procState > ActivityManager.PROCESS_STATE_TOP) {
19954             // A client of one of our services or providers is in the top state.  We
19955             // *may* want to be in the top state, but not if we are already running in
19956             // the background for some other reason.  For the decision here, we are going
19957             // to pick out a few specific states that we want to remain in when a client
19958             // is top (states that tend to be longer-term) and otherwise allow it to go
19959             // to the top state.
19960             switch (procState) {
19961                 case ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND:
19962                 case ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND:
19963                 case ActivityManager.PROCESS_STATE_SERVICE:
19964                     // These all are longer-term states, so pull them up to the top
19965                     // of the background states, but not all the way to the top state.
19966                     procState = ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE;
19967                     break;
19968                 default:
19969                     // Otherwise, top is a better choice, so take it.
19970                     procState = ActivityManager.PROCESS_STATE_TOP;
19971                     break;
19972             }
19973         }
19974
19975         if (procState >= ActivityManager.PROCESS_STATE_CACHED_EMPTY) {
19976             if (app.hasClientActivities) {
19977                 // This is a cached process, but with client activities.  Mark it so.
19978                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT;
19979                 app.adjType = "cch-client-act";
19980             } else if (app.treatLikeActivity) {
19981                 // This is a cached process, but somebody wants us to treat it like it has
19982                 // an activity, okay!
19983                 procState = ActivityManager.PROCESS_STATE_CACHED_ACTIVITY;
19984                 app.adjType = "cch-as-act";
19985             }
19986         }
19987
19988         if (adj == ProcessList.SERVICE_ADJ) {
19989             if (doingAll) {
19990                 app.serviceb = mNewNumAServiceProcs > (mNumServiceProcs/3);
19991                 mNewNumServiceProcs++;
19992                 //Slog.i(TAG, "ADJ " + app + " serviceb=" + app.serviceb);
19993                 if (!app.serviceb) {
19994                     // This service isn't far enough down on the LRU list to
19995                     // normally be a B service, but if we are low on RAM and it
19996                     // is large we want to force it down since we would prefer to
19997                     // keep launcher over it.
19998                     if (mLastMemoryLevel > ProcessStats.ADJ_MEM_FACTOR_NORMAL
19999                             && app.lastPss >= mProcessList.getCachedRestoreThresholdKb()) {
20000                         app.serviceHighRam = true;
20001                         app.serviceb = true;
20002                         //Slog.i(TAG, "ADJ " + app + " high ram!");
20003                     } else {
20004                         mNewNumAServiceProcs++;
20005                         //Slog.i(TAG, "ADJ " + app + " not high ram!");
20006                     }
20007                 } else {
20008                     app.serviceHighRam = false;
20009                 }
20010             }
20011             if (app.serviceb) {
20012                 adj = ProcessList.SERVICE_B_ADJ;
20013             }
20014         }
20015
20016         app.curRawAdj = adj;
20017
20018         //Slog.i(TAG, "OOM ADJ " + app + ": pid=" + app.pid +
20019         //      " adj=" + adj + " curAdj=" + app.curAdj + " maxAdj=" + app.maxAdj);
20020         if (adj > app.maxAdj) {
20021             adj = app.maxAdj;
20022             if (app.maxAdj <= ProcessList.PERCEPTIBLE_APP_ADJ) {
20023                 schedGroup = ProcessList.SCHED_GROUP_DEFAULT;
20024             }
20025         }
20026
20027         // Do final modification to adj.  Everything we do between here and applying
20028         // the final setAdj must be done in this function, because we will also use
20029         // it when computing the final cached adj later.  Note that we don't need to
20030         // worry about this for max adj above, since max adj will always be used to
20031         // keep it out of the cached vaues.
20032         app.curAdj = app.modifyRawOomAdj(adj);
20033         app.curSchedGroup = schedGroup;
20034         app.curProcState = procState;
20035         app.foregroundActivities = foregroundActivities;
20036
20037         return app.curRawAdj;
20038     }
20039
20040     /**
20041      * Record new PSS sample for a process.
20042      */
20043     void recordPssSampleLocked(ProcessRecord proc, int procState, long pss, long uss, long swapPss,
20044             long now) {
20045         EventLogTags.writeAmPss(proc.pid, proc.uid, proc.processName, pss * 1024, uss * 1024,
20046                 swapPss * 1024);
20047         proc.lastPssTime = now;
20048         proc.baseProcessTracker.addPss(pss, uss, true, proc.pkgList);
20049         if (DEBUG_PSS) Slog.d(TAG_PSS,
20050                 "PSS of " + proc.toShortString() + ": " + pss + " lastPss=" + proc.lastPss
20051                 + " state=" + ProcessList.makeProcStateString(procState));
20052         if (proc.initialIdlePss == 0) {
20053             proc.initialIdlePss = pss;
20054         }
20055         proc.lastPss = pss;
20056         proc.lastSwapPss = swapPss;
20057         if (procState >= ActivityManager.PROCESS_STATE_HOME) {
20058             proc.lastCachedPss = pss;
20059             proc.lastCachedSwapPss = swapPss;
20060         }
20061
20062         final SparseArray<Pair<Long, String>> watchUids
20063                 = mMemWatchProcesses.getMap().get(proc.processName);
20064         Long check = null;
20065         if (watchUids != null) {
20066             Pair<Long, String> val = watchUids.get(proc.uid);
20067             if (val == null) {
20068                 val = watchUids.get(0);
20069             }
20070             if (val != null) {
20071                 check = val.first;
20072             }
20073         }
20074         if (check != null) {
20075             if ((pss * 1024) >= check && proc.thread != null && mMemWatchDumpProcName == null) {
20076                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
20077                 if (!isDebuggable) {
20078                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) != 0) {
20079                         isDebuggable = true;
20080                     }
20081                 }
20082                 if (isDebuggable) {
20083                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check + "; reporting");
20084                     final ProcessRecord myProc = proc;
20085                     final File heapdumpFile = DumpHeapProvider.getJavaFile();
20086                     mMemWatchDumpProcName = proc.processName;
20087                     mMemWatchDumpFile = heapdumpFile.toString();
20088                     mMemWatchDumpPid = proc.pid;
20089                     mMemWatchDumpUid = proc.uid;
20090                     BackgroundThread.getHandler().post(new Runnable() {
20091                         @Override
20092                         public void run() {
20093                             revokeUriPermission(ActivityThread.currentActivityThread()
20094                                             .getApplicationThread(),
20095                                     DumpHeapActivity.JAVA_URI,
20096                                     Intent.FLAG_GRANT_READ_URI_PERMISSION
20097                                             | Intent.FLAG_GRANT_WRITE_URI_PERMISSION,
20098                                     UserHandle.myUserId());
20099                             ParcelFileDescriptor fd = null;
20100                             try {
20101                                 heapdumpFile.delete();
20102                                 fd = ParcelFileDescriptor.open(heapdumpFile,
20103                                         ParcelFileDescriptor.MODE_CREATE |
20104                                                 ParcelFileDescriptor.MODE_TRUNCATE |
20105                                                 ParcelFileDescriptor.MODE_WRITE_ONLY |
20106                                                 ParcelFileDescriptor.MODE_APPEND);
20107                                 IApplicationThread thread = myProc.thread;
20108                                 if (thread != null) {
20109                                     try {
20110                                         if (DEBUG_PSS) Slog.d(TAG_PSS,
20111                                                 "Requesting dump heap from "
20112                                                 + myProc + " to " + heapdumpFile);
20113                                         thread.dumpHeap(true, heapdumpFile.toString(), fd);
20114                                     } catch (RemoteException e) {
20115                                     }
20116                                 }
20117                             } catch (FileNotFoundException e) {
20118                                 e.printStackTrace();
20119                             } finally {
20120                                 if (fd != null) {
20121                                     try {
20122                                         fd.close();
20123                                     } catch (IOException e) {
20124                                     }
20125                                 }
20126                             }
20127                         }
20128                     });
20129                 } else {
20130                     Slog.w(TAG, "Process " + proc + " exceeded pss limit " + check
20131                             + ", but debugging not enabled");
20132                 }
20133             }
20134         }
20135     }
20136
20137     /**
20138      * Schedule PSS collection of a process.
20139      */
20140     void requestPssLocked(ProcessRecord proc, int procState) {
20141         if (mPendingPssProcesses.contains(proc)) {
20142             return;
20143         }
20144         if (mPendingPssProcesses.size() == 0) {
20145             mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20146         }
20147         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of: " + proc);
20148         proc.pssProcState = procState;
20149         mPendingPssProcesses.add(proc);
20150     }
20151
20152     /**
20153      * Schedule PSS collection of all processes.
20154      */
20155     void requestPssAllProcsLocked(long now, boolean always, boolean memLowered) {
20156         if (!always) {
20157             if (now < (mLastFullPssTime +
20158                     (memLowered ? FULL_PSS_LOWERED_INTERVAL : FULL_PSS_MIN_INTERVAL))) {
20159                 return;
20160             }
20161         }
20162         if (DEBUG_PSS) Slog.d(TAG_PSS, "Requesting PSS of all procs!  memLowered=" + memLowered);
20163         mLastFullPssTime = now;
20164         mFullPssPending = true;
20165         mPendingPssProcesses.ensureCapacity(mLruProcesses.size());
20166         mPendingPssProcesses.clear();
20167         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
20168             ProcessRecord app = mLruProcesses.get(i);
20169             if (app.thread == null
20170                     || app.curProcState == ActivityManager.PROCESS_STATE_NONEXISTENT) {
20171                 continue;
20172             }
20173             if (memLowered || now > (app.lastStateTime+ProcessList.PSS_ALL_INTERVAL)) {
20174                 app.pssProcState = app.setProcState;
20175                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20176                         mTestPssMode, isSleepingLocked(), now);
20177                 mPendingPssProcesses.add(app);
20178             }
20179         }
20180         mBgHandler.sendEmptyMessage(COLLECT_PSS_BG_MSG);
20181     }
20182
20183     public void setTestPssMode(boolean enabled) {
20184         synchronized (this) {
20185             mTestPssMode = enabled;
20186             if (enabled) {
20187                 // Whenever we enable the mode, we want to take a snapshot all of current
20188                 // process mem use.
20189                 requestPssAllProcsLocked(SystemClock.uptimeMillis(), true, true);
20190             }
20191         }
20192     }
20193
20194     /**
20195      * Ask a given process to GC right now.
20196      */
20197     final void performAppGcLocked(ProcessRecord app) {
20198         try {
20199             app.lastRequestedGc = SystemClock.uptimeMillis();
20200             if (app.thread != null) {
20201                 if (app.reportLowMemory) {
20202                     app.reportLowMemory = false;
20203                     app.thread.scheduleLowMemory();
20204                 } else {
20205                     app.thread.processInBackground();
20206                 }
20207             }
20208         } catch (Exception e) {
20209             // whatever.
20210         }
20211     }
20212
20213     /**
20214      * Returns true if things are idle enough to perform GCs.
20215      */
20216     private final boolean canGcNowLocked() {
20217         boolean processingBroadcasts = false;
20218         for (BroadcastQueue q : mBroadcastQueues) {
20219             if (q.mParallelBroadcasts.size() != 0 || q.mOrderedBroadcasts.size() != 0) {
20220                 processingBroadcasts = true;
20221             }
20222         }
20223         return !processingBroadcasts
20224                 && (isSleepingLocked() || mStackSupervisor.allResumedActivitiesIdle());
20225     }
20226
20227     /**
20228      * Perform GCs on all processes that are waiting for it, but only
20229      * if things are idle.
20230      */
20231     final void performAppGcsLocked() {
20232         final int N = mProcessesToGc.size();
20233         if (N <= 0) {
20234             return;
20235         }
20236         if (canGcNowLocked()) {
20237             while (mProcessesToGc.size() > 0) {
20238                 ProcessRecord proc = mProcessesToGc.remove(0);
20239                 if (proc.curRawAdj > ProcessList.PERCEPTIBLE_APP_ADJ || proc.reportLowMemory) {
20240                     if ((proc.lastRequestedGc+GC_MIN_INTERVAL)
20241                             <= SystemClock.uptimeMillis()) {
20242                         // To avoid spamming the system, we will GC processes one
20243                         // at a time, waiting a few seconds between each.
20244                         performAppGcLocked(proc);
20245                         scheduleAppGcsLocked();
20246                         return;
20247                     } else {
20248                         // It hasn't been long enough since we last GCed this
20249                         // process...  put it in the list to wait for its time.
20250                         addProcessToGcListLocked(proc);
20251                         break;
20252                     }
20253                 }
20254             }
20255
20256             scheduleAppGcsLocked();
20257         }
20258     }
20259
20260     /**
20261      * If all looks good, perform GCs on all processes waiting for them.
20262      */
20263     final void performAppGcsIfAppropriateLocked() {
20264         if (canGcNowLocked()) {
20265             performAppGcsLocked();
20266             return;
20267         }
20268         // Still not idle, wait some more.
20269         scheduleAppGcsLocked();
20270     }
20271
20272     /**
20273      * Schedule the execution of all pending app GCs.
20274      */
20275     final void scheduleAppGcsLocked() {
20276         mHandler.removeMessages(GC_BACKGROUND_PROCESSES_MSG);
20277
20278         if (mProcessesToGc.size() > 0) {
20279             // Schedule a GC for the time to the next process.
20280             ProcessRecord proc = mProcessesToGc.get(0);
20281             Message msg = mHandler.obtainMessage(GC_BACKGROUND_PROCESSES_MSG);
20282
20283             long when = proc.lastRequestedGc + GC_MIN_INTERVAL;
20284             long now = SystemClock.uptimeMillis();
20285             if (when < (now+GC_TIMEOUT)) {
20286                 when = now + GC_TIMEOUT;
20287             }
20288             mHandler.sendMessageAtTime(msg, when);
20289         }
20290     }
20291
20292     /**
20293      * Add a process to the array of processes waiting to be GCed.  Keeps the
20294      * list in sorted order by the last GC time.  The process can't already be
20295      * on the list.
20296      */
20297     final void addProcessToGcListLocked(ProcessRecord proc) {
20298         boolean added = false;
20299         for (int i=mProcessesToGc.size()-1; i>=0; i--) {
20300             if (mProcessesToGc.get(i).lastRequestedGc <
20301                     proc.lastRequestedGc) {
20302                 added = true;
20303                 mProcessesToGc.add(i+1, proc);
20304                 break;
20305             }
20306         }
20307         if (!added) {
20308             mProcessesToGc.add(0, proc);
20309         }
20310     }
20311
20312     /**
20313      * Set up to ask a process to GC itself.  This will either do it
20314      * immediately, or put it on the list of processes to gc the next
20315      * time things are idle.
20316      */
20317     final void scheduleAppGcLocked(ProcessRecord app) {
20318         long now = SystemClock.uptimeMillis();
20319         if ((app.lastRequestedGc+GC_MIN_INTERVAL) > now) {
20320             return;
20321         }
20322         if (!mProcessesToGc.contains(app)) {
20323             addProcessToGcListLocked(app);
20324             scheduleAppGcsLocked();
20325         }
20326     }
20327
20328     final void checkExcessivePowerUsageLocked(boolean doKills) {
20329         updateCpuStatsNow();
20330
20331         BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20332         boolean doWakeKills = doKills;
20333         boolean doCpuKills = doKills;
20334         if (mLastPowerCheckRealtime == 0) {
20335             doWakeKills = false;
20336         }
20337         if (mLastPowerCheckUptime == 0) {
20338             doCpuKills = false;
20339         }
20340         if (stats.isScreenOn()) {
20341             doWakeKills = false;
20342         }
20343         final long curRealtime = SystemClock.elapsedRealtime();
20344         final long realtimeSince = curRealtime - mLastPowerCheckRealtime;
20345         final long curUptime = SystemClock.uptimeMillis();
20346         final long uptimeSince = curUptime - mLastPowerCheckUptime;
20347         mLastPowerCheckRealtime = curRealtime;
20348         mLastPowerCheckUptime = curUptime;
20349         if (realtimeSince < WAKE_LOCK_MIN_CHECK_DURATION) {
20350             doWakeKills = false;
20351         }
20352         if (uptimeSince < CPU_MIN_CHECK_DURATION) {
20353             doCpuKills = false;
20354         }
20355         int i = mLruProcesses.size();
20356         while (i > 0) {
20357             i--;
20358             ProcessRecord app = mLruProcesses.get(i);
20359             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20360                 long wtime;
20361                 synchronized (stats) {
20362                     wtime = stats.getProcessWakeTime(app.info.uid,
20363                             app.pid, curRealtime);
20364                 }
20365                 long wtimeUsed = wtime - app.lastWakeTime;
20366                 long cputimeUsed = app.curCpuTime - app.lastCpuTime;
20367                 if (DEBUG_POWER) {
20368                     StringBuilder sb = new StringBuilder(128);
20369                     sb.append("Wake for ");
20370                     app.toShortString(sb);
20371                     sb.append(": over ");
20372                     TimeUtils.formatDuration(realtimeSince, sb);
20373                     sb.append(" used ");
20374                     TimeUtils.formatDuration(wtimeUsed, sb);
20375                     sb.append(" (");
20376                     sb.append((wtimeUsed*100)/realtimeSince);
20377                     sb.append("%)");
20378                     Slog.i(TAG_POWER, sb.toString());
20379                     sb.setLength(0);
20380                     sb.append("CPU for ");
20381                     app.toShortString(sb);
20382                     sb.append(": over ");
20383                     TimeUtils.formatDuration(uptimeSince, sb);
20384                     sb.append(" used ");
20385                     TimeUtils.formatDuration(cputimeUsed, sb);
20386                     sb.append(" (");
20387                     sb.append((cputimeUsed*100)/uptimeSince);
20388                     sb.append("%)");
20389                     Slog.i(TAG_POWER, sb.toString());
20390                 }
20391                 // If a process has held a wake lock for more
20392                 // than 50% of the time during this period,
20393                 // that sounds bad.  Kill!
20394                 if (doWakeKills && realtimeSince > 0
20395                         && ((wtimeUsed*100)/realtimeSince) >= 50) {
20396                     synchronized (stats) {
20397                         stats.reportExcessiveWakeLocked(app.info.uid, app.processName,
20398                                 realtimeSince, wtimeUsed);
20399                     }
20400                     app.kill("excessive wake held " + wtimeUsed + " during " + realtimeSince, true);
20401                     app.baseProcessTracker.reportExcessiveWake(app.pkgList);
20402                 } else if (doCpuKills && uptimeSince > 0
20403                         && ((cputimeUsed*100)/uptimeSince) >= 25) {
20404                     synchronized (stats) {
20405                         stats.reportExcessiveCpuLocked(app.info.uid, app.processName,
20406                                 uptimeSince, cputimeUsed);
20407                     }
20408                     app.kill("excessive cpu " + cputimeUsed + " during " + uptimeSince, true);
20409                     app.baseProcessTracker.reportExcessiveCpu(app.pkgList);
20410                 } else {
20411                     app.lastWakeTime = wtime;
20412                     app.lastCpuTime = app.curCpuTime;
20413                 }
20414             }
20415         }
20416     }
20417
20418     private final boolean applyOomAdjLocked(ProcessRecord app, boolean doingAll, long now,
20419             long nowElapsed) {
20420         boolean success = true;
20421
20422         if (app.curRawAdj != app.setRawAdj) {
20423             app.setRawAdj = app.curRawAdj;
20424         }
20425
20426         int changes = 0;
20427
20428         if (app.curAdj != app.setAdj) {
20429             ProcessList.setOomAdj(app.pid, app.info.uid, app.curAdj);
20430             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20431                     "Set " + app.pid + " " + app.processName + " adj " + app.curAdj + ": "
20432                     + app.adjType);
20433             app.setAdj = app.curAdj;
20434             app.verifiedAdj = ProcessList.INVALID_ADJ;
20435         }
20436
20437         if (app.setSchedGroup != app.curSchedGroup) {
20438             int oldSchedGroup = app.setSchedGroup;
20439             app.setSchedGroup = app.curSchedGroup;
20440             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20441                     "Setting sched group of " + app.processName
20442                     + " to " + app.curSchedGroup);
20443             if (app.waitingToKill != null && app.curReceiver == null
20444                     && app.setSchedGroup == ProcessList.SCHED_GROUP_BACKGROUND) {
20445                 app.kill(app.waitingToKill, true);
20446                 success = false;
20447             } else {
20448                 int processGroup;
20449                 switch (app.curSchedGroup) {
20450                     case ProcessList.SCHED_GROUP_BACKGROUND:
20451                         processGroup = Process.THREAD_GROUP_BG_NONINTERACTIVE;
20452                         break;
20453                     case ProcessList.SCHED_GROUP_TOP_APP:
20454                     case ProcessList.SCHED_GROUP_TOP_APP_BOUND:
20455                         processGroup = Process.THREAD_GROUP_TOP_APP;
20456                         break;
20457                     default:
20458                         processGroup = Process.THREAD_GROUP_DEFAULT;
20459                         break;
20460                 }
20461                 long oldId = Binder.clearCallingIdentity();
20462                 try {
20463                     Process.setProcessGroup(app.pid, processGroup);
20464                     if (app.curSchedGroup == ProcessList.SCHED_GROUP_TOP_APP) {
20465                         // do nothing if we already switched to RT
20466                         if (oldSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20467                             // Switch VR thread for app to SCHED_FIFO
20468                             if (mInVrMode && app.vrThreadTid != 0) {
20469                                 try {
20470                                     Process.setThreadScheduler(app.vrThreadTid,
20471                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20472                                 } catch (IllegalArgumentException e) {
20473                                     // thread died, ignore
20474                                 }
20475                             }
20476                             if (mUseFifoUiScheduling) {
20477                                 // Switch UI pipeline for app to SCHED_FIFO
20478                                 app.savedPriority = Process.getThreadPriority(app.pid);
20479                                 try {
20480                                     Process.setThreadScheduler(app.pid,
20481                                         Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20482                                 } catch (IllegalArgumentException e) {
20483                                     // thread died, ignore
20484                                 }
20485                                 if (app.renderThreadTid != 0) {
20486                                     try {
20487                                         Process.setThreadScheduler(app.renderThreadTid,
20488                                             Process.SCHED_FIFO | Process.SCHED_RESET_ON_FORK, 1);
20489                                     } catch (IllegalArgumentException e) {
20490                                         // thread died, ignore
20491                                     }
20492                                     if (DEBUG_OOM_ADJ) {
20493                                         Slog.d("UI_FIFO", "Set RenderThread (TID " +
20494                                             app.renderThreadTid + ") to FIFO");
20495                                     }
20496                                 } else {
20497                                     if (DEBUG_OOM_ADJ) {
20498                                         Slog.d("UI_FIFO", "Not setting RenderThread TID");
20499                                     }
20500                                 }
20501                             } else {
20502                                 // Boost priority for top app UI and render threads
20503                                 Process.setThreadPriority(app.pid, -10);
20504                                 if (app.renderThreadTid != 0) {
20505                                     try {
20506                                         Process.setThreadPriority(app.renderThreadTid, -10);
20507                                     } catch (IllegalArgumentException e) {
20508                                         // thread died, ignore
20509                                     }
20510                                 }
20511                             }
20512                         }
20513                     } else if (oldSchedGroup == ProcessList.SCHED_GROUP_TOP_APP &&
20514                                app.curSchedGroup != ProcessList.SCHED_GROUP_TOP_APP) {
20515                         // Reset VR thread to SCHED_OTHER
20516                         // Safe to do even if we're not in VR mode
20517                         if (app.vrThreadTid != 0) {
20518                             Process.setThreadScheduler(app.vrThreadTid, Process.SCHED_OTHER, 0);
20519                         }
20520                         if (mUseFifoUiScheduling) {
20521                             // Reset UI pipeline to SCHED_OTHER
20522                             Process.setThreadScheduler(app.pid, Process.SCHED_OTHER, 0);
20523                             Process.setThreadPriority(app.pid, app.savedPriority);
20524                             if (app.renderThreadTid != 0) {
20525                                 Process.setThreadScheduler(app.renderThreadTid,
20526                                     Process.SCHED_OTHER, 0);
20527                                 Process.setThreadPriority(app.renderThreadTid, -4);
20528                             }
20529                         } else {
20530                             // Reset priority for top app UI and render threads
20531                             Process.setThreadPriority(app.pid, 0);
20532                             if (app.renderThreadTid != 0) {
20533                                 Process.setThreadPriority(app.renderThreadTid, 0);
20534                             }
20535                         }
20536                     }
20537                 } catch (Exception e) {
20538                     Slog.w(TAG, "Failed setting process group of " + app.pid
20539                             + " to " + app.curSchedGroup);
20540                     e.printStackTrace();
20541                 } finally {
20542                     Binder.restoreCallingIdentity(oldId);
20543                 }
20544             }
20545         }
20546         if (app.repForegroundActivities != app.foregroundActivities) {
20547             app.repForegroundActivities = app.foregroundActivities;
20548             changes |= ProcessChangeItem.CHANGE_ACTIVITIES;
20549         }
20550         if (app.repProcState != app.curProcState) {
20551             app.repProcState = app.curProcState;
20552             changes |= ProcessChangeItem.CHANGE_PROCESS_STATE;
20553             if (app.thread != null) {
20554                 try {
20555                     if (false) {
20556                         //RuntimeException h = new RuntimeException("here");
20557                         Slog.i(TAG, "Sending new process state " + app.repProcState
20558                                 + " to " + app /*, h*/);
20559                     }
20560                     app.thread.setProcessState(app.repProcState);
20561                 } catch (RemoteException e) {
20562                 }
20563             }
20564         }
20565         if (app.setProcState == ActivityManager.PROCESS_STATE_NONEXISTENT
20566                 || ProcessList.procStatesDifferForMem(app.curProcState, app.setProcState)) {
20567             if (false && mTestPssMode && app.setProcState >= 0 && app.lastStateTime <= (now-200)) {
20568                 // Experimental code to more aggressively collect pss while
20569                 // running test...  the problem is that this tends to collect
20570                 // the data right when a process is transitioning between process
20571                 // states, which well tend to give noisy data.
20572                 long start = SystemClock.uptimeMillis();
20573                 long pss = Debug.getPss(app.pid, mTmpLong, null);
20574                 recordPssSampleLocked(app, app.curProcState, pss, mTmpLong[0], mTmpLong[1], now);
20575                 mPendingPssProcesses.remove(app);
20576                 Slog.i(TAG, "Recorded pss for " + app + " state " + app.setProcState
20577                         + " to " + app.curProcState + ": "
20578                         + (SystemClock.uptimeMillis()-start) + "ms");
20579             }
20580             app.lastStateTime = now;
20581             app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, true,
20582                     mTestPssMode, isSleepingLocked(), now);
20583             if (DEBUG_PSS) Slog.d(TAG_PSS, "Process state change from "
20584                     + ProcessList.makeProcStateString(app.setProcState) + " to "
20585                     + ProcessList.makeProcStateString(app.curProcState) + " next pss in "
20586                     + (app.nextPssTime-now) + ": " + app);
20587         } else {
20588             if (now > app.nextPssTime || (now > (app.lastPssTime+ProcessList.PSS_MAX_INTERVAL)
20589                     && now > (app.lastStateTime+ProcessList.minTimeFromStateChange(
20590                     mTestPssMode)))) {
20591                 requestPssLocked(app, app.setProcState);
20592                 app.nextPssTime = ProcessList.computeNextPssTime(app.curProcState, false,
20593                         mTestPssMode, isSleepingLocked(), now);
20594             } else if (false && DEBUG_PSS) Slog.d(TAG_PSS,
20595                     "Not requesting PSS of " + app + ": next=" + (app.nextPssTime-now));
20596         }
20597         if (app.setProcState != app.curProcState) {
20598             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
20599                     "Proc state change of " + app.processName
20600                             + " to " + app.curProcState);
20601             boolean setImportant = app.setProcState < ActivityManager.PROCESS_STATE_SERVICE;
20602             boolean curImportant = app.curProcState < ActivityManager.PROCESS_STATE_SERVICE;
20603             if (setImportant && !curImportant) {
20604                 // This app is no longer something we consider important enough to allow to
20605                 // use arbitrary amounts of battery power.  Note
20606                 // its current wake lock time to later know to kill it if
20607                 // it is not behaving well.
20608                 BatteryStatsImpl stats = mBatteryStatsService.getActiveStatistics();
20609                 synchronized (stats) {
20610                     app.lastWakeTime = stats.getProcessWakeTime(app.info.uid,
20611                             app.pid, nowElapsed);
20612                 }
20613                 app.lastCpuTime = app.curCpuTime;
20614
20615             }
20616             // Inform UsageStats of important process state change
20617             // Must be called before updating setProcState
20618             maybeUpdateUsageStatsLocked(app, nowElapsed);
20619
20620             app.setProcState = app.curProcState;
20621             if (app.setProcState >= ActivityManager.PROCESS_STATE_HOME) {
20622                 app.notCachedSinceIdle = false;
20623             }
20624             if (!doingAll) {
20625                 setProcessTrackerStateLocked(app, mProcessStats.getMemFactorLocked(), now);
20626             } else {
20627                 app.procStateChanged = true;
20628             }
20629         } else if (app.reportedInteraction && (nowElapsed-app.interactionEventTime)
20630                 > USAGE_STATS_INTERACTION_INTERVAL) {
20631             // For apps that sit around for a long time in the interactive state, we need
20632             // to report this at least once a day so they don't go idle.
20633             maybeUpdateUsageStatsLocked(app, nowElapsed);
20634         }
20635
20636         if (changes != 0) {
20637             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20638                     "Changes in " + app + ": " + changes);
20639             int i = mPendingProcessChanges.size()-1;
20640             ProcessChangeItem item = null;
20641             while (i >= 0) {
20642                 item = mPendingProcessChanges.get(i);
20643                 if (item.pid == app.pid) {
20644                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20645                             "Re-using existing item: " + item);
20646                     break;
20647                 }
20648                 i--;
20649             }
20650             if (i < 0) {
20651                 // No existing item in pending changes; need a new one.
20652                 final int NA = mAvailProcessChanges.size();
20653                 if (NA > 0) {
20654                     item = mAvailProcessChanges.remove(NA-1);
20655                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20656                             "Retrieving available item: " + item);
20657                 } else {
20658                     item = new ProcessChangeItem();
20659                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20660                             "Allocating new item: " + item);
20661                 }
20662                 item.changes = 0;
20663                 item.pid = app.pid;
20664                 item.uid = app.info.uid;
20665                 if (mPendingProcessChanges.size() == 0) {
20666                     if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20667                             "*** Enqueueing dispatch processes changed!");
20668                     mUiHandler.obtainMessage(DISPATCH_PROCESSES_CHANGED_UI_MSG).sendToTarget();
20669                 }
20670                 mPendingProcessChanges.add(item);
20671             }
20672             item.changes |= changes;
20673             item.processState = app.repProcState;
20674             item.foregroundActivities = app.repForegroundActivities;
20675             if (DEBUG_PROCESS_OBSERVERS) Slog.i(TAG_PROCESS_OBSERVERS,
20676                     "Item " + Integer.toHexString(System.identityHashCode(item))
20677                     + " " + app.toShortString() + ": changes=" + item.changes
20678                     + " procState=" + item.processState
20679                     + " foreground=" + item.foregroundActivities
20680                     + " type=" + app.adjType + " source=" + app.adjSource
20681                     + " target=" + app.adjTarget);
20682         }
20683
20684         return success;
20685     }
20686
20687     private final void enqueueUidChangeLocked(UidRecord uidRec, int uid, int change) {
20688         final UidRecord.ChangeItem pendingChange;
20689         if (uidRec == null || uidRec.pendingChange == null) {
20690             if (mPendingUidChanges.size() == 0) {
20691                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20692                         "*** Enqueueing dispatch uid changed!");
20693                 mUiHandler.obtainMessage(DISPATCH_UIDS_CHANGED_UI_MSG).sendToTarget();
20694             }
20695             final int NA = mAvailUidChanges.size();
20696             if (NA > 0) {
20697                 pendingChange = mAvailUidChanges.remove(NA-1);
20698                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20699                         "Retrieving available item: " + pendingChange);
20700             } else {
20701                 pendingChange = new UidRecord.ChangeItem();
20702                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20703                         "Allocating new item: " + pendingChange);
20704             }
20705             if (uidRec != null) {
20706                 uidRec.pendingChange = pendingChange;
20707                 if (change == UidRecord.CHANGE_GONE && !uidRec.idle) {
20708                     // If this uid is going away, and we haven't yet reported it is gone,
20709                     // then do so now.
20710                     change = UidRecord.CHANGE_GONE_IDLE;
20711                 }
20712             } else if (uid < 0) {
20713                 throw new IllegalArgumentException("No UidRecord or uid");
20714             }
20715             pendingChange.uidRecord = uidRec;
20716             pendingChange.uid = uidRec != null ? uidRec.uid : uid;
20717             mPendingUidChanges.add(pendingChange);
20718         } else {
20719             pendingChange = uidRec.pendingChange;
20720             if (change == UidRecord.CHANGE_GONE && pendingChange.change == UidRecord.CHANGE_IDLE) {
20721                 change = UidRecord.CHANGE_GONE_IDLE;
20722             }
20723         }
20724         pendingChange.change = change;
20725         pendingChange.processState = uidRec != null
20726                 ? uidRec.setProcState : ActivityManager.PROCESS_STATE_NONEXISTENT;
20727     }
20728
20729     private void maybeUpdateProviderUsageStatsLocked(ProcessRecord app, String providerPkgName,
20730             String authority) {
20731         if (app == null) return;
20732         if (app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND) {
20733             UserState userState = mUserController.getStartedUserStateLocked(app.userId);
20734             if (userState == null) return;
20735             final long now = SystemClock.elapsedRealtime();
20736             Long lastReported = userState.mProviderLastReportedFg.get(authority);
20737             if (lastReported == null || lastReported < now - 60 * 1000L) {
20738                 if (mSystemReady) {
20739                     // Cannot touch the user stats if not system ready
20740                     mUsageStatsService.reportContentProviderUsage(
20741                             authority, providerPkgName, app.userId);
20742                 }
20743                 userState.mProviderLastReportedFg.put(authority, now);
20744             }
20745         }
20746     }
20747
20748     private void maybeUpdateUsageStatsLocked(ProcessRecord app, long nowElapsed) {
20749         if (DEBUG_USAGE_STATS) {
20750             Slog.d(TAG, "Checking proc [" + Arrays.toString(app.getPackageList())
20751                     + "] state changes: old = " + app.setProcState + ", new = "
20752                     + app.curProcState);
20753         }
20754         if (mUsageStatsService == null) {
20755             return;
20756         }
20757         boolean isInteraction;
20758         // To avoid some abuse patterns, we are going to be careful about what we consider
20759         // to be an app interaction.  Being the top activity doesn't count while the display
20760         // is sleeping, nor do short foreground services.
20761         if (app.curProcState <= ActivityManager.PROCESS_STATE_BOUND_FOREGROUND_SERVICE) {
20762             isInteraction = true;
20763             app.fgInteractionTime = 0;
20764         } else if (app.curProcState <= ActivityManager.PROCESS_STATE_TOP_SLEEPING) {
20765             if (app.fgInteractionTime == 0) {
20766                 app.fgInteractionTime = nowElapsed;
20767                 isInteraction = false;
20768             } else {
20769                 isInteraction = nowElapsed > app.fgInteractionTime + SERVICE_USAGE_INTERACTION_TIME;
20770             }
20771         } else {
20772             // If the app was being forced to the foreground, by say a Toast, then
20773             // no need to treat it as an interaction
20774             isInteraction = app.forcingToForeground == null
20775                     && app.curProcState <= ActivityManager.PROCESS_STATE_IMPORTANT_FOREGROUND;
20776             app.fgInteractionTime = 0;
20777         }
20778         if (isInteraction && (!app.reportedInteraction
20779                 || (nowElapsed-app.interactionEventTime) > USAGE_STATS_INTERACTION_INTERVAL)) {
20780             app.interactionEventTime = nowElapsed;
20781             String[] packages = app.getPackageList();
20782             if (packages != null) {
20783                 for (int i = 0; i < packages.length; i++) {
20784                     mUsageStatsService.reportEvent(packages[i], app.userId,
20785                             UsageEvents.Event.SYSTEM_INTERACTION);
20786                 }
20787             }
20788         }
20789         app.reportedInteraction = isInteraction;
20790         if (!isInteraction) {
20791             app.interactionEventTime = 0;
20792         }
20793     }
20794
20795     private final void setProcessTrackerStateLocked(ProcessRecord proc, int memFactor, long now) {
20796         if (proc.thread != null) {
20797             if (proc.baseProcessTracker != null) {
20798                 proc.baseProcessTracker.setState(proc.repProcState, memFactor, now, proc.pkgList);
20799             }
20800         }
20801     }
20802
20803     private final boolean updateOomAdjLocked(ProcessRecord app, int cachedAdj,
20804             ProcessRecord TOP_APP, boolean doingAll, long now) {
20805         if (app.thread == null) {
20806             return false;
20807         }
20808
20809         computeOomAdjLocked(app, cachedAdj, TOP_APP, doingAll, now);
20810
20811         return applyOomAdjLocked(app, doingAll, now, SystemClock.elapsedRealtime());
20812     }
20813
20814     final void updateProcessForegroundLocked(ProcessRecord proc, boolean isForeground,
20815             boolean oomAdj) {
20816         if (isForeground != proc.foregroundServices) {
20817             proc.foregroundServices = isForeground;
20818             ArrayList<ProcessRecord> curProcs = mForegroundPackages.get(proc.info.packageName,
20819                     proc.info.uid);
20820             if (isForeground) {
20821                 if (curProcs == null) {
20822                     curProcs = new ArrayList<ProcessRecord>();
20823                     mForegroundPackages.put(proc.info.packageName, proc.info.uid, curProcs);
20824                 }
20825                 if (!curProcs.contains(proc)) {
20826                     curProcs.add(proc);
20827                     mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_FOREGROUND_START,
20828                             proc.info.packageName, proc.info.uid);
20829                 }
20830             } else {
20831                 if (curProcs != null) {
20832                     if (curProcs.remove(proc)) {
20833                         mBatteryStatsService.noteEvent(
20834                                 BatteryStats.HistoryItem.EVENT_FOREGROUND_FINISH,
20835                                 proc.info.packageName, proc.info.uid);
20836                         if (curProcs.size() <= 0) {
20837                             mForegroundPackages.remove(proc.info.packageName, proc.info.uid);
20838                         }
20839                     }
20840                 }
20841             }
20842             if (oomAdj) {
20843                 updateOomAdjLocked();
20844             }
20845         }
20846     }
20847
20848     private final ActivityRecord resumedAppLocked() {
20849         ActivityRecord act = mStackSupervisor.resumedAppLocked();
20850         String pkg;
20851         int uid;
20852         if (act != null) {
20853             pkg = act.packageName;
20854             uid = act.info.applicationInfo.uid;
20855         } else {
20856             pkg = null;
20857             uid = -1;
20858         }
20859         // Has the UID or resumed package name changed?
20860         if (uid != mCurResumedUid || (pkg != mCurResumedPackage
20861                 && (pkg == null || !pkg.equals(mCurResumedPackage)))) {
20862             if (mCurResumedPackage != null) {
20863                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_FINISH,
20864                         mCurResumedPackage, mCurResumedUid);
20865             }
20866             mCurResumedPackage = pkg;
20867             mCurResumedUid = uid;
20868             if (mCurResumedPackage != null) {
20869                 mBatteryStatsService.noteEvent(BatteryStats.HistoryItem.EVENT_TOP_START,
20870                         mCurResumedPackage, mCurResumedUid);
20871             }
20872         }
20873         return act;
20874     }
20875
20876     final boolean updateOomAdjLocked(ProcessRecord app) {
20877         final ActivityRecord TOP_ACT = resumedAppLocked();
20878         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20879         final boolean wasCached = app.cached;
20880
20881         mAdjSeq++;
20882
20883         // This is the desired cached adjusment we want to tell it to use.
20884         // If our app is currently cached, we know it, and that is it.  Otherwise,
20885         // we don't know it yet, and it needs to now be cached we will then
20886         // need to do a complete oom adj.
20887         final int cachedAdj = app.curRawAdj >= ProcessList.CACHED_APP_MIN_ADJ
20888                 ? app.curRawAdj : ProcessList.UNKNOWN_ADJ;
20889         boolean success = updateOomAdjLocked(app, cachedAdj, TOP_APP, false,
20890                 SystemClock.uptimeMillis());
20891         if (wasCached != app.cached || app.curRawAdj == ProcessList.UNKNOWN_ADJ) {
20892             // Changed to/from cached state, so apps after it in the LRU
20893             // list may also be changed.
20894             updateOomAdjLocked();
20895         }
20896         return success;
20897     }
20898
20899     final void updateOomAdjLocked() {
20900         final ActivityRecord TOP_ACT = resumedAppLocked();
20901         final ProcessRecord TOP_APP = TOP_ACT != null ? TOP_ACT.app : null;
20902         final long now = SystemClock.uptimeMillis();
20903         final long nowElapsed = SystemClock.elapsedRealtime();
20904         final long oldTime = now - ProcessList.MAX_EMPTY_TIME;
20905         final int N = mLruProcesses.size();
20906
20907         if (false) {
20908             RuntimeException e = new RuntimeException();
20909             e.fillInStackTrace();
20910             Slog.i(TAG, "updateOomAdj: top=" + TOP_ACT, e);
20911         }
20912
20913         // Reset state in all uid records.
20914         for (int i=mActiveUids.size()-1; i>=0; i--) {
20915             final UidRecord uidRec = mActiveUids.valueAt(i);
20916             if (false && DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
20917                     "Starting update of " + uidRec);
20918             uidRec.reset();
20919         }
20920
20921         mStackSupervisor.rankTaskLayersIfNeeded();
20922
20923         mAdjSeq++;
20924         mNewNumServiceProcs = 0;
20925         mNewNumAServiceProcs = 0;
20926
20927         final int emptyProcessLimit;
20928         final int cachedProcessLimit;
20929         if (mProcessLimit <= 0) {
20930             emptyProcessLimit = cachedProcessLimit = 0;
20931         } else if (mProcessLimit == 1) {
20932             emptyProcessLimit = 1;
20933             cachedProcessLimit = 0;
20934         } else {
20935             emptyProcessLimit = ProcessList.computeEmptyProcessLimit(mProcessLimit);
20936             cachedProcessLimit = mProcessLimit - emptyProcessLimit;
20937         }
20938
20939         // Let's determine how many processes we have running vs.
20940         // how many slots we have for background processes; we may want
20941         // to put multiple processes in a slot of there are enough of
20942         // them.
20943         int numSlots = (ProcessList.CACHED_APP_MAX_ADJ
20944                 - ProcessList.CACHED_APP_MIN_ADJ + 1) / 2;
20945         int numEmptyProcs = N - mNumNonCachedProcs - mNumCachedHiddenProcs;
20946         if (numEmptyProcs > cachedProcessLimit) {
20947             // If there are more empty processes than our limit on cached
20948             // processes, then use the cached process limit for the factor.
20949             // This ensures that the really old empty processes get pushed
20950             // down to the bottom, so if we are running low on memory we will
20951             // have a better chance at keeping around more cached processes
20952             // instead of a gazillion empty processes.
20953             numEmptyProcs = cachedProcessLimit;
20954         }
20955         int emptyFactor = numEmptyProcs/numSlots;
20956         if (emptyFactor < 1) emptyFactor = 1;
20957         int cachedFactor = (mNumCachedHiddenProcs > 0 ? mNumCachedHiddenProcs : 1)/numSlots;
20958         if (cachedFactor < 1) cachedFactor = 1;
20959         int stepCached = 0;
20960         int stepEmpty = 0;
20961         int numCached = 0;
20962         int numEmpty = 0;
20963         int numTrimming = 0;
20964
20965         mNumNonCachedProcs = 0;
20966         mNumCachedHiddenProcs = 0;
20967
20968         // First update the OOM adjustment for each of the
20969         // application processes based on their current state.
20970         int curCachedAdj = ProcessList.CACHED_APP_MIN_ADJ;
20971         int nextCachedAdj = curCachedAdj+1;
20972         int curEmptyAdj = ProcessList.CACHED_APP_MIN_ADJ;
20973         int nextEmptyAdj = curEmptyAdj+2;
20974         for (int i=N-1; i>=0; i--) {
20975             ProcessRecord app = mLruProcesses.get(i);
20976             if (app == null) {
20977                 continue;
20978             }
20979             if (!app.killedByAm && app.thread != null) {
20980                 app.procStateChanged = false;
20981                 computeOomAdjLocked(app, ProcessList.UNKNOWN_ADJ, TOP_APP, true, now);
20982
20983                 // If we haven't yet assigned the final cached adj
20984                 // to the process, do that now.
20985                 if (app.curAdj >= ProcessList.UNKNOWN_ADJ) {
20986                     switch (app.curProcState) {
20987                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
20988                         case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
20989                             // This process is a cached process holding activities...
20990                             // assign it the next cached value for that type, and then
20991                             // step that cached level.
20992                             app.curRawAdj = curCachedAdj;
20993                             app.curAdj = app.modifyRawOomAdj(curCachedAdj);
20994                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning activity LRU #" + i
20995                                     + " adj: " + app.curAdj + " (curCachedAdj=" + curCachedAdj
20996                                     + ")");
20997                             if (curCachedAdj != nextCachedAdj) {
20998                                 stepCached++;
20999                                 if (stepCached >= cachedFactor) {
21000                                     stepCached = 0;
21001                                     curCachedAdj = nextCachedAdj;
21002                                     nextCachedAdj += 2;
21003                                     if (nextCachedAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21004                                         nextCachedAdj = ProcessList.CACHED_APP_MAX_ADJ;
21005                                     }
21006                                 }
21007                             }
21008                             break;
21009                         default:
21010                             // For everything else, assign next empty cached process
21011                             // level and bump that up.  Note that this means that
21012                             // long-running services that have dropped down to the
21013                             // cached level will be treated as empty (since their process
21014                             // state is still as a service), which is what we want.
21015                             app.curRawAdj = curEmptyAdj;
21016                             app.curAdj = app.modifyRawOomAdj(curEmptyAdj);
21017                             if (DEBUG_LRU && false) Slog.d(TAG_LRU, "Assigning empty LRU #" + i
21018                                     + " adj: " + app.curAdj + " (curEmptyAdj=" + curEmptyAdj
21019                                     + ")");
21020                             if (curEmptyAdj != nextEmptyAdj) {
21021                                 stepEmpty++;
21022                                 if (stepEmpty >= emptyFactor) {
21023                                     stepEmpty = 0;
21024                                     curEmptyAdj = nextEmptyAdj;
21025                                     nextEmptyAdj += 2;
21026                                     if (nextEmptyAdj > ProcessList.CACHED_APP_MAX_ADJ) {
21027                                         nextEmptyAdj = ProcessList.CACHED_APP_MAX_ADJ;
21028                                     }
21029                                 }
21030                             }
21031                             break;
21032                     }
21033                 }
21034
21035                 applyOomAdjLocked(app, true, now, nowElapsed);
21036
21037                 // Count the number of process types.
21038                 switch (app.curProcState) {
21039                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY:
21040                     case ActivityManager.PROCESS_STATE_CACHED_ACTIVITY_CLIENT:
21041                         mNumCachedHiddenProcs++;
21042                         numCached++;
21043                         if (numCached > cachedProcessLimit) {
21044                             app.kill("cached #" + numCached, true);
21045                         }
21046                         break;
21047                     case ActivityManager.PROCESS_STATE_CACHED_EMPTY:
21048                         if (numEmpty > ProcessList.TRIM_EMPTY_APPS
21049                                 && app.lastActivityTime < oldTime) {
21050                             app.kill("empty for "
21051                                     + ((oldTime + ProcessList.MAX_EMPTY_TIME - app.lastActivityTime)
21052                                     / 1000) + "s", true);
21053                         } else {
21054                             numEmpty++;
21055                             if (numEmpty > emptyProcessLimit) {
21056                                 app.kill("empty #" + numEmpty, true);
21057                             }
21058                         }
21059                         break;
21060                     default:
21061                         mNumNonCachedProcs++;
21062                         break;
21063                 }
21064
21065                 if (app.isolated && app.services.size() <= 0) {
21066                     // If this is an isolated process, and there are no
21067                     // services running in it, then the process is no longer
21068                     // needed.  We agressively kill these because we can by
21069                     // definition not re-use the same process again, and it is
21070                     // good to avoid having whatever code was running in them
21071                     // left sitting around after no longer needed.
21072                     app.kill("isolated not needed", true);
21073                 } else {
21074                     // Keeping this process, update its uid.
21075                     final UidRecord uidRec = app.uidRecord;
21076                     if (uidRec != null && uidRec.curProcState > app.curProcState) {
21077                         uidRec.curProcState = app.curProcState;
21078                     }
21079                 }
21080
21081                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21082                         && !app.killedByAm) {
21083                     numTrimming++;
21084                 }
21085             }
21086         }
21087
21088         mNumServiceProcs = mNewNumServiceProcs;
21089
21090         // Now determine the memory trimming level of background processes.
21091         // Unfortunately we need to start at the back of the list to do this
21092         // properly.  We only do this if the number of background apps we
21093         // are managing to keep around is less than half the maximum we desire;
21094         // if we are keeping a good number around, we'll let them use whatever
21095         // memory they want.
21096         final int numCachedAndEmpty = numCached + numEmpty;
21097         int memFactor;
21098         if (numCached <= ProcessList.TRIM_CACHED_APPS
21099                 && numEmpty <= ProcessList.TRIM_EMPTY_APPS) {
21100             if (numCachedAndEmpty <= ProcessList.TRIM_CRITICAL_THRESHOLD) {
21101                 memFactor = ProcessStats.ADJ_MEM_FACTOR_CRITICAL;
21102             } else if (numCachedAndEmpty <= ProcessList.TRIM_LOW_THRESHOLD) {
21103                 memFactor = ProcessStats.ADJ_MEM_FACTOR_LOW;
21104             } else {
21105                 memFactor = ProcessStats.ADJ_MEM_FACTOR_MODERATE;
21106             }
21107         } else {
21108             memFactor = ProcessStats.ADJ_MEM_FACTOR_NORMAL;
21109         }
21110         // We always allow the memory level to go up (better).  We only allow it to go
21111         // down if we are in a state where that is allowed, *and* the total number of processes
21112         // has gone down since last time.
21113         if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "oom: memFactor=" + memFactor
21114                 + " last=" + mLastMemoryLevel + " allowLow=" + mAllowLowerMemLevel
21115                 + " numProcs=" + mLruProcesses.size() + " last=" + mLastNumProcesses);
21116         if (memFactor > mLastMemoryLevel) {
21117             if (!mAllowLowerMemLevel || mLruProcesses.size() >= mLastNumProcesses) {
21118                 memFactor = mLastMemoryLevel;
21119                 if (DEBUG_OOM_ADJ) Slog.d(TAG_OOM_ADJ, "Keeping last mem factor!");
21120             }
21121         }
21122         if (memFactor != mLastMemoryLevel) {
21123             EventLogTags.writeAmMemFactor(memFactor, mLastMemoryLevel);
21124         }
21125         mLastMemoryLevel = memFactor;
21126         mLastNumProcesses = mLruProcesses.size();
21127         boolean allChanged = mProcessStats.setMemFactorLocked(memFactor, !isSleepingLocked(), now);
21128         final int trackerMemFactor = mProcessStats.getMemFactorLocked();
21129         if (memFactor != ProcessStats.ADJ_MEM_FACTOR_NORMAL) {
21130             if (mLowRamStartTime == 0) {
21131                 mLowRamStartTime = now;
21132             }
21133             int step = 0;
21134             int fgTrimLevel;
21135             switch (memFactor) {
21136                 case ProcessStats.ADJ_MEM_FACTOR_CRITICAL:
21137                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_CRITICAL;
21138                     break;
21139                 case ProcessStats.ADJ_MEM_FACTOR_LOW:
21140                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_LOW;
21141                     break;
21142                 default:
21143                     fgTrimLevel = ComponentCallbacks2.TRIM_MEMORY_RUNNING_MODERATE;
21144                     break;
21145             }
21146             int factor = numTrimming/3;
21147             int minFactor = 2;
21148             if (mHomeProcess != null) minFactor++;
21149             if (mPreviousProcess != null) minFactor++;
21150             if (factor < minFactor) factor = minFactor;
21151             int curLevel = ComponentCallbacks2.TRIM_MEMORY_COMPLETE;
21152             for (int i=N-1; i>=0; i--) {
21153                 ProcessRecord app = mLruProcesses.get(i);
21154                 if (app == null) {
21155                     continue;
21156                 }
21157                 if (allChanged || app.procStateChanged) {
21158                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21159                     app.procStateChanged = false;
21160                 }
21161                 if (app.curProcState >= ActivityManager.PROCESS_STATE_HOME
21162                         && !app.killedByAm) {
21163                     if (app.trimMemoryLevel < curLevel && app.thread != null) {
21164                         try {
21165                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21166                                     "Trimming memory of " + app.processName + " to " + curLevel);
21167                             app.thread.scheduleTrimMemory(curLevel);
21168                         } catch (RemoteException e) {
21169                         }
21170                         if (false) {
21171                             // For now we won't do this; our memory trimming seems
21172                             // to be good enough at this point that destroying
21173                             // activities causes more harm than good.
21174                             if (curLevel >= ComponentCallbacks2.TRIM_MEMORY_COMPLETE
21175                                     && app != mHomeProcess && app != mPreviousProcess) {
21176                                 // Need to do this on its own message because the stack may not
21177                                 // be in a consistent state at this point.
21178                                 // For these apps we will also finish their activities
21179                                 // to help them free memory.
21180                                 mStackSupervisor.scheduleDestroyAllActivities(app, "trim");
21181                             }
21182                         }
21183                     }
21184                     app.trimMemoryLevel = curLevel;
21185                     step++;
21186                     if (step >= factor) {
21187                         step = 0;
21188                         switch (curLevel) {
21189                             case ComponentCallbacks2.TRIM_MEMORY_COMPLETE:
21190                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_MODERATE;
21191                                 break;
21192                             case ComponentCallbacks2.TRIM_MEMORY_MODERATE:
21193                                 curLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21194                                 break;
21195                         }
21196                     }
21197                 } else if (app.curProcState == ActivityManager.PROCESS_STATE_HEAVY_WEIGHT) {
21198                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_BACKGROUND
21199                             && app.thread != null) {
21200                         try {
21201                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21202                                     "Trimming memory of heavy-weight " + app.processName
21203                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21204                             app.thread.scheduleTrimMemory(
21205                                     ComponentCallbacks2.TRIM_MEMORY_BACKGROUND);
21206                         } catch (RemoteException e) {
21207                         }
21208                     }
21209                     app.trimMemoryLevel = ComponentCallbacks2.TRIM_MEMORY_BACKGROUND;
21210                 } else {
21211                     if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21212                             || app.systemNoUi) && app.pendingUiClean) {
21213                         // If this application is now in the background and it
21214                         // had done UI, then give it the special trim level to
21215                         // have it free UI resources.
21216                         final int level = ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN;
21217                         if (app.trimMemoryLevel < level && app.thread != null) {
21218                             try {
21219                                 if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21220                                         "Trimming memory of bg-ui " + app.processName
21221                                         + " to " + level);
21222                                 app.thread.scheduleTrimMemory(level);
21223                             } catch (RemoteException e) {
21224                             }
21225                         }
21226                         app.pendingUiClean = false;
21227                     }
21228                     if (app.trimMemoryLevel < fgTrimLevel && app.thread != null) {
21229                         try {
21230                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21231                                     "Trimming memory of fg " + app.processName
21232                                     + " to " + fgTrimLevel);
21233                             app.thread.scheduleTrimMemory(fgTrimLevel);
21234                         } catch (RemoteException e) {
21235                         }
21236                     }
21237                     app.trimMemoryLevel = fgTrimLevel;
21238                 }
21239             }
21240         } else {
21241             if (mLowRamStartTime != 0) {
21242                 mLowRamTimeSinceLastIdle += now - mLowRamStartTime;
21243                 mLowRamStartTime = 0;
21244             }
21245             for (int i=N-1; i>=0; i--) {
21246                 ProcessRecord app = mLruProcesses.get(i);
21247                 if (allChanged || app.procStateChanged) {
21248                     setProcessTrackerStateLocked(app, trackerMemFactor, now);
21249                     app.procStateChanged = false;
21250                 }
21251                 if ((app.curProcState >= ActivityManager.PROCESS_STATE_IMPORTANT_BACKGROUND
21252                         || app.systemNoUi) && app.pendingUiClean) {
21253                     if (app.trimMemoryLevel < ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN
21254                             && app.thread != null) {
21255                         try {
21256                             if (DEBUG_SWITCH || DEBUG_OOM_ADJ) Slog.v(TAG_OOM_ADJ,
21257                                     "Trimming memory of ui hidden " + app.processName
21258                                     + " to " + ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21259                             app.thread.scheduleTrimMemory(
21260                                     ComponentCallbacks2.TRIM_MEMORY_UI_HIDDEN);
21261                         } catch (RemoteException e) {
21262                         }
21263                     }
21264                     app.pendingUiClean = false;
21265                 }
21266                 app.trimMemoryLevel = 0;
21267             }
21268         }
21269
21270         if (mAlwaysFinishActivities) {
21271             // Need to do this on its own message because the stack may not
21272             // be in a consistent state at this point.
21273             mStackSupervisor.scheduleDestroyAllActivities(null, "always-finish");
21274         }
21275
21276         if (allChanged) {
21277             requestPssAllProcsLocked(now, false, mProcessStats.isMemFactorLowered());
21278         }
21279
21280         // Update from any uid changes.
21281         for (int i=mActiveUids.size()-1; i>=0; i--) {
21282             final UidRecord uidRec = mActiveUids.valueAt(i);
21283             int uidChange = UidRecord.CHANGE_PROCSTATE;
21284             if (uidRec.setProcState != uidRec.curProcState) {
21285                 if (DEBUG_UID_OBSERVERS) Slog.i(TAG_UID_OBSERVERS,
21286                         "Changes in " + uidRec + ": proc state from " + uidRec.setProcState
21287                         + " to " + uidRec.curProcState);
21288                 if (ActivityManager.isProcStateBackground(uidRec.curProcState)) {
21289                     if (!ActivityManager.isProcStateBackground(uidRec.setProcState)) {
21290                         uidRec.lastBackgroundTime = nowElapsed;
21291                         if (!mHandler.hasMessages(IDLE_UIDS_MSG)) {
21292                             // Note: the background settle time is in elapsed realtime, while
21293                             // the handler time base is uptime.  All this means is that we may
21294                             // stop background uids later than we had intended, but that only
21295                             // happens because the device was sleeping so we are okay anyway.
21296                             mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG, BACKGROUND_SETTLE_TIME);
21297                         }
21298                     }
21299                 } else {
21300                     if (uidRec.idle) {
21301                         uidChange = UidRecord.CHANGE_ACTIVE;
21302                         uidRec.idle = false;
21303                     }
21304                     uidRec.lastBackgroundTime = 0;
21305                 }
21306                 uidRec.setProcState = uidRec.curProcState;
21307                 enqueueUidChangeLocked(uidRec, -1, uidChange);
21308                 noteUidProcessState(uidRec.uid, uidRec.curProcState);
21309             }
21310         }
21311
21312         if (mProcessStats.shouldWriteNowLocked(now)) {
21313             mHandler.post(new Runnable() {
21314                 @Override public void run() {
21315                     synchronized (ActivityManagerService.this) {
21316                         mProcessStats.writeStateAsyncLocked();
21317                     }
21318                 }
21319             });
21320         }
21321
21322         if (DEBUG_OOM_ADJ) {
21323             final long duration = SystemClock.uptimeMillis() - now;
21324             if (false) {
21325                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms",
21326                         new RuntimeException("here").fillInStackTrace());
21327             } else {
21328                 Slog.d(TAG_OOM_ADJ, "Did OOM ADJ in " + duration + "ms");
21329             }
21330         }
21331     }
21332
21333     final void idleUids() {
21334         synchronized (this) {
21335             final long nowElapsed = SystemClock.elapsedRealtime();
21336             final long maxBgTime = nowElapsed - BACKGROUND_SETTLE_TIME;
21337             long nextTime = 0;
21338             for (int i=mActiveUids.size()-1; i>=0; i--) {
21339                 final UidRecord uidRec = mActiveUids.valueAt(i);
21340                 final long bgTime = uidRec.lastBackgroundTime;
21341                 if (bgTime > 0 && !uidRec.idle) {
21342                     if (bgTime <= maxBgTime) {
21343                         uidRec.idle = true;
21344                         doStopUidLocked(uidRec.uid, uidRec);
21345                     } else {
21346                         if (nextTime == 0 || nextTime > bgTime) {
21347                             nextTime = bgTime;
21348                         }
21349                     }
21350                 }
21351             }
21352             if (nextTime > 0) {
21353                 mHandler.removeMessages(IDLE_UIDS_MSG);
21354                 mHandler.sendEmptyMessageDelayed(IDLE_UIDS_MSG,
21355                         nextTime + BACKGROUND_SETTLE_TIME - nowElapsed);
21356             }
21357         }
21358     }
21359
21360     final void runInBackgroundDisabled(int uid) {
21361         synchronized (this) {
21362             UidRecord uidRec = mActiveUids.get(uid);
21363             if (uidRec != null) {
21364                 // This uid is actually running...  should it be considered background now?
21365                 if (uidRec.idle) {
21366                     doStopUidLocked(uidRec.uid, uidRec);
21367                 }
21368             } else {
21369                 // This uid isn't actually running...  still send a report about it being "stopped".
21370                 doStopUidLocked(uid, null);
21371             }
21372         }
21373     }
21374
21375     final void doStopUidLocked(int uid, final UidRecord uidRec) {
21376         mServices.stopInBackgroundLocked(uid);
21377         enqueueUidChangeLocked(uidRec, uid, UidRecord.CHANGE_IDLE);
21378     }
21379
21380     final void trimApplications() {
21381         synchronized (this) {
21382             int i;
21383
21384             // First remove any unused application processes whose package
21385             // has been removed.
21386             for (i=mRemovedProcesses.size()-1; i>=0; i--) {
21387                 final ProcessRecord app = mRemovedProcesses.get(i);
21388                 if (app.activities.size() == 0
21389                         && app.curReceiver == null && app.services.size() == 0) {
21390                     Slog.i(
21391                         TAG, "Exiting empty application process "
21392                         + app.toShortString() + " ("
21393                         + (app.thread != null ? app.thread.asBinder() : null)
21394                         + ")\n");
21395                     if (app.pid > 0 && app.pid != MY_PID) {
21396                         app.kill("empty", false);
21397                     } else {
21398                         try {
21399                             app.thread.scheduleExit();
21400                         } catch (Exception e) {
21401                             // Ignore exceptions.
21402                         }
21403                     }
21404                     cleanUpApplicationRecordLocked(app, false, true, -1, false /*replacingPid*/);
21405                     mRemovedProcesses.remove(i);
21406
21407                     if (app.persistent) {
21408                         addAppLocked(app.info, false, null /* ABI override */);
21409                     }
21410                 }
21411             }
21412
21413             // Now update the oom adj for all processes.
21414             updateOomAdjLocked();
21415         }
21416     }
21417
21418     /** This method sends the specified signal to each of the persistent apps */
21419     public void signalPersistentProcesses(int sig) throws RemoteException {
21420         if (sig != Process.SIGNAL_USR1) {
21421             throw new SecurityException("Only SIGNAL_USR1 is allowed");
21422         }
21423
21424         synchronized (this) {
21425             if (checkCallingPermission(android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES)
21426                     != PackageManager.PERMISSION_GRANTED) {
21427                 throw new SecurityException("Requires permission "
21428                         + android.Manifest.permission.SIGNAL_PERSISTENT_PROCESSES);
21429             }
21430
21431             for (int i = mLruProcesses.size() - 1 ; i >= 0 ; i--) {
21432                 ProcessRecord r = mLruProcesses.get(i);
21433                 if (r.thread != null && r.persistent) {
21434                     Process.sendSignal(r.pid, sig);
21435                 }
21436             }
21437         }
21438     }
21439
21440     private void stopProfilerLocked(ProcessRecord proc, int profileType) {
21441         if (proc == null || proc == mProfileProc) {
21442             proc = mProfileProc;
21443             profileType = mProfileType;
21444             clearProfilerLocked();
21445         }
21446         if (proc == null) {
21447             return;
21448         }
21449         try {
21450             proc.thread.profilerControl(false, null, profileType);
21451         } catch (RemoteException e) {
21452             throw new IllegalStateException("Process disappeared");
21453         }
21454     }
21455
21456     private void clearProfilerLocked() {
21457         if (mProfileFd != null) {
21458             try {
21459                 mProfileFd.close();
21460             } catch (IOException e) {
21461             }
21462         }
21463         mProfileApp = null;
21464         mProfileProc = null;
21465         mProfileFile = null;
21466         mProfileType = 0;
21467         mAutoStopProfiler = false;
21468         mSamplingInterval = 0;
21469     }
21470
21471     public boolean profileControl(String process, int userId, boolean start,
21472             ProfilerInfo profilerInfo, int profileType) throws RemoteException {
21473
21474         try {
21475             synchronized (this) {
21476                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21477                 // its own permission.
21478                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21479                         != PackageManager.PERMISSION_GRANTED) {
21480                     throw new SecurityException("Requires permission "
21481                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21482                 }
21483
21484                 if (start && (profilerInfo == null || profilerInfo.profileFd == null)) {
21485                     throw new IllegalArgumentException("null profile info or fd");
21486                 }
21487
21488                 ProcessRecord proc = null;
21489                 if (process != null) {
21490                     proc = findProcessLocked(process, userId, "profileControl");
21491                 }
21492
21493                 if (start && (proc == null || proc.thread == null)) {
21494                     throw new IllegalArgumentException("Unknown process: " + process);
21495                 }
21496
21497                 if (start) {
21498                     stopProfilerLocked(null, 0);
21499                     setProfileApp(proc.info, proc.processName, profilerInfo);
21500                     mProfileProc = proc;
21501                     mProfileType = profileType;
21502                     ParcelFileDescriptor fd = profilerInfo.profileFd;
21503                     try {
21504                         fd = fd.dup();
21505                     } catch (IOException e) {
21506                         fd = null;
21507                     }
21508                     profilerInfo.profileFd = fd;
21509                     proc.thread.profilerControl(start, profilerInfo, profileType);
21510                     fd = null;
21511                     mProfileFd = null;
21512                 } else {
21513                     stopProfilerLocked(proc, profileType);
21514                     if (profilerInfo != null && profilerInfo.profileFd != null) {
21515                         try {
21516                             profilerInfo.profileFd.close();
21517                         } catch (IOException e) {
21518                         }
21519                     }
21520                 }
21521
21522                 return true;
21523             }
21524         } catch (RemoteException e) {
21525             throw new IllegalStateException("Process disappeared");
21526         } finally {
21527             if (profilerInfo != null && profilerInfo.profileFd != null) {
21528                 try {
21529                     profilerInfo.profileFd.close();
21530                 } catch (IOException e) {
21531                 }
21532             }
21533         }
21534     }
21535
21536     private ProcessRecord findProcessLocked(String process, int userId, String callName) {
21537         userId = mUserController.handleIncomingUser(Binder.getCallingPid(), Binder.getCallingUid(),
21538                 userId, true, ALLOW_FULL_ONLY, callName, null);
21539         ProcessRecord proc = null;
21540         try {
21541             int pid = Integer.parseInt(process);
21542             synchronized (mPidsSelfLocked) {
21543                 proc = mPidsSelfLocked.get(pid);
21544             }
21545         } catch (NumberFormatException e) {
21546         }
21547
21548         if (proc == null) {
21549             ArrayMap<String, SparseArray<ProcessRecord>> all
21550                     = mProcessNames.getMap();
21551             SparseArray<ProcessRecord> procs = all.get(process);
21552             if (procs != null && procs.size() > 0) {
21553                 proc = procs.valueAt(0);
21554                 if (userId != UserHandle.USER_ALL && proc.userId != userId) {
21555                     for (int i=1; i<procs.size(); i++) {
21556                         ProcessRecord thisProc = procs.valueAt(i);
21557                         if (thisProc.userId == userId) {
21558                             proc = thisProc;
21559                             break;
21560                         }
21561                     }
21562                 }
21563             }
21564         }
21565
21566         return proc;
21567     }
21568
21569     public boolean dumpHeap(String process, int userId, boolean managed,
21570             String path, ParcelFileDescriptor fd) throws RemoteException {
21571
21572         try {
21573             synchronized (this) {
21574                 // note: hijacking SET_ACTIVITY_WATCHER, but should be changed to
21575                 // its own permission (same as profileControl).
21576                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21577                         != PackageManager.PERMISSION_GRANTED) {
21578                     throw new SecurityException("Requires permission "
21579                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21580                 }
21581
21582                 if (fd == null) {
21583                     throw new IllegalArgumentException("null fd");
21584                 }
21585
21586                 ProcessRecord proc = findProcessLocked(process, userId, "dumpHeap");
21587                 if (proc == null || proc.thread == null) {
21588                     throw new IllegalArgumentException("Unknown process: " + process);
21589                 }
21590
21591                 boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21592                 if (!isDebuggable) {
21593                     if ((proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21594                         throw new SecurityException("Process not debuggable: " + proc);
21595                     }
21596                 }
21597
21598                 proc.thread.dumpHeap(managed, path, fd);
21599                 fd = null;
21600                 return true;
21601             }
21602         } catch (RemoteException e) {
21603             throw new IllegalStateException("Process disappeared");
21604         } finally {
21605             if (fd != null) {
21606                 try {
21607                     fd.close();
21608                 } catch (IOException e) {
21609                 }
21610             }
21611         }
21612     }
21613
21614     @Override
21615     public void setDumpHeapDebugLimit(String processName, int uid, long maxMemSize,
21616             String reportPackage) {
21617         if (processName != null) {
21618             enforceCallingPermission(android.Manifest.permission.SET_DEBUG_APP,
21619                     "setDumpHeapDebugLimit()");
21620         } else {
21621             synchronized (mPidsSelfLocked) {
21622                 ProcessRecord proc = mPidsSelfLocked.get(Binder.getCallingPid());
21623                 if (proc == null) {
21624                     throw new SecurityException("No process found for calling pid "
21625                             + Binder.getCallingPid());
21626                 }
21627                 if (!Build.IS_DEBUGGABLE
21628                         && (proc.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21629                     throw new SecurityException("Not running a debuggable build");
21630                 }
21631                 processName = proc.processName;
21632                 uid = proc.uid;
21633                 if (reportPackage != null && !proc.pkgList.containsKey(reportPackage)) {
21634                     throw new SecurityException("Package " + reportPackage + " is not running in "
21635                             + proc);
21636                 }
21637             }
21638         }
21639         synchronized (this) {
21640             if (maxMemSize > 0) {
21641                 mMemWatchProcesses.put(processName, uid, new Pair(maxMemSize, reportPackage));
21642             } else {
21643                 if (uid != 0) {
21644                     mMemWatchProcesses.remove(processName, uid);
21645                 } else {
21646                     mMemWatchProcesses.getMap().remove(processName);
21647                 }
21648             }
21649         }
21650     }
21651
21652     @Override
21653     public void dumpHeapFinished(String path) {
21654         synchronized (this) {
21655             if (Binder.getCallingPid() != mMemWatchDumpPid) {
21656                 Slog.w(TAG, "dumpHeapFinished: Calling pid " + Binder.getCallingPid()
21657                         + " does not match last pid " + mMemWatchDumpPid);
21658                 return;
21659             }
21660             if (mMemWatchDumpFile == null || !mMemWatchDumpFile.equals(path)) {
21661                 Slog.w(TAG, "dumpHeapFinished: Calling path " + path
21662                         + " does not match last path " + mMemWatchDumpFile);
21663                 return;
21664             }
21665             if (DEBUG_PSS) Slog.d(TAG_PSS, "Dump heap finished for " + path);
21666             mHandler.sendEmptyMessage(POST_DUMP_HEAP_NOTIFICATION_MSG);
21667         }
21668     }
21669
21670     /** In this method we try to acquire our lock to make sure that we have not deadlocked */
21671     public void monitor() {
21672         synchronized (this) { }
21673     }
21674
21675     void onCoreSettingsChange(Bundle settings) {
21676         for (int i = mLruProcesses.size() - 1; i >= 0; i--) {
21677             ProcessRecord processRecord = mLruProcesses.get(i);
21678             try {
21679                 if (processRecord.thread != null) {
21680                     processRecord.thread.setCoreSettings(settings);
21681                 }
21682             } catch (RemoteException re) {
21683                 /* ignore */
21684             }
21685         }
21686     }
21687
21688     // Multi-user methods
21689
21690     /**
21691      * Start user, if its not already running, but don't bring it to foreground.
21692      */
21693     @Override
21694     public boolean startUserInBackground(final int userId) {
21695         return mUserController.startUser(userId, /* foreground */ false);
21696     }
21697
21698     @Override
21699     public boolean unlockUser(int userId, byte[] token, byte[] secret, IProgressListener listener) {
21700         return mUserController.unlockUser(userId, token, secret, listener);
21701     }
21702
21703     @Override
21704     public boolean switchUser(final int targetUserId) {
21705         enforceShellRestriction(UserManager.DISALLOW_DEBUGGING_FEATURES, targetUserId);
21706         UserInfo currentUserInfo;
21707         UserInfo targetUserInfo;
21708         synchronized (this) {
21709             int currentUserId = mUserController.getCurrentUserIdLocked();
21710             currentUserInfo = mUserController.getUserInfo(currentUserId);
21711             targetUserInfo = mUserController.getUserInfo(targetUserId);
21712             if (targetUserInfo == null) {
21713                 Slog.w(TAG, "No user info for user #" + targetUserId);
21714                 return false;
21715             }
21716             if (!targetUserInfo.isDemo() && UserManager.isDeviceInDemoMode(mContext)) {
21717                 Slog.w(TAG, "Cannot switch to non-demo user #" + targetUserId
21718                         + " when device is in demo mode");
21719                 return false;
21720             }
21721             if (!targetUserInfo.supportsSwitchTo()) {
21722                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not supported");
21723                 return false;
21724             }
21725             if (targetUserInfo.isManagedProfile()) {
21726                 Slog.w(TAG, "Cannot switch to User #" + targetUserId + ": not a full user");
21727                 return false;
21728             }
21729             mUserController.setTargetUserIdLocked(targetUserId);
21730         }
21731         Pair<UserInfo, UserInfo> userNames = new Pair<>(currentUserInfo, targetUserInfo);
21732         mUiHandler.removeMessages(START_USER_SWITCH_UI_MSG);
21733         mUiHandler.sendMessage(mUiHandler.obtainMessage(START_USER_SWITCH_UI_MSG, userNames));
21734         return true;
21735     }
21736
21737     void scheduleStartProfilesLocked() {
21738         if (!mHandler.hasMessages(START_PROFILES_MSG)) {
21739             mHandler.sendMessageDelayed(mHandler.obtainMessage(START_PROFILES_MSG),
21740                     DateUtils.SECOND_IN_MILLIS);
21741         }
21742     }
21743
21744     @Override
21745     public int stopUser(final int userId, boolean force, final IStopUserCallback callback) {
21746         return mUserController.stopUser(userId, force, callback);
21747     }
21748
21749     @Override
21750     public UserInfo getCurrentUser() {
21751         return mUserController.getCurrentUser();
21752     }
21753
21754     @Override
21755     public boolean isUserRunning(int userId, int flags) {
21756         if (!mUserController.isSameProfileGroup(userId, UserHandle.getCallingUserId())
21757                 && checkCallingPermission(INTERACT_ACROSS_USERS)
21758                     != PackageManager.PERMISSION_GRANTED) {
21759             String msg = "Permission Denial: isUserRunning() from pid="
21760                     + Binder.getCallingPid()
21761                     + ", uid=" + Binder.getCallingUid()
21762                     + " requires " + INTERACT_ACROSS_USERS;
21763             Slog.w(TAG, msg);
21764             throw new SecurityException(msg);
21765         }
21766         synchronized (this) {
21767             return mUserController.isUserRunningLocked(userId, flags);
21768         }
21769     }
21770
21771     @Override
21772     public int[] getRunningUserIds() {
21773         if (checkCallingPermission(INTERACT_ACROSS_USERS)
21774                 != PackageManager.PERMISSION_GRANTED) {
21775             String msg = "Permission Denial: isUserRunning() from pid="
21776                     + Binder.getCallingPid()
21777                     + ", uid=" + Binder.getCallingUid()
21778                     + " requires " + INTERACT_ACROSS_USERS;
21779             Slog.w(TAG, msg);
21780             throw new SecurityException(msg);
21781         }
21782         synchronized (this) {
21783             return mUserController.getStartedUserArrayLocked();
21784         }
21785     }
21786
21787     @Override
21788     public void registerUserSwitchObserver(IUserSwitchObserver observer, String name) {
21789         mUserController.registerUserSwitchObserver(observer, name);
21790     }
21791
21792     @Override
21793     public void unregisterUserSwitchObserver(IUserSwitchObserver observer) {
21794         mUserController.unregisterUserSwitchObserver(observer);
21795     }
21796
21797     ApplicationInfo getAppInfoForUser(ApplicationInfo info, int userId) {
21798         if (info == null) return null;
21799         ApplicationInfo newInfo = new ApplicationInfo(info);
21800         newInfo.initForUser(userId);
21801         return newInfo;
21802     }
21803
21804     public boolean isUserStopped(int userId) {
21805         synchronized (this) {
21806             return mUserController.getStartedUserStateLocked(userId) == null;
21807         }
21808     }
21809
21810     ActivityInfo getActivityInfoForUser(ActivityInfo aInfo, int userId) {
21811         if (aInfo == null
21812                 || (userId < 1 && aInfo.applicationInfo.uid < UserHandle.PER_USER_RANGE)) {
21813             return aInfo;
21814         }
21815
21816         ActivityInfo info = new ActivityInfo(aInfo);
21817         info.applicationInfo = getAppInfoForUser(info.applicationInfo, userId);
21818         return info;
21819     }
21820
21821     private boolean processSanityChecksLocked(ProcessRecord process) {
21822         if (process == null || process.thread == null) {
21823             return false;
21824         }
21825
21826         boolean isDebuggable = "1".equals(SystemProperties.get(SYSTEM_DEBUGGABLE, "0"));
21827         if (!isDebuggable) {
21828             if ((process.info.flags&ApplicationInfo.FLAG_DEBUGGABLE) == 0) {
21829                 return false;
21830             }
21831         }
21832
21833         return true;
21834     }
21835
21836     public boolean startBinderTracking() throws RemoteException {
21837         synchronized (this) {
21838             mBinderTransactionTrackingEnabled = true;
21839             // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21840             // permission (same as profileControl).
21841             if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21842                     != PackageManager.PERMISSION_GRANTED) {
21843                 throw new SecurityException("Requires permission "
21844                         + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21845             }
21846
21847             for (int i = 0; i < mLruProcesses.size(); i++) {
21848                 ProcessRecord process = mLruProcesses.get(i);
21849                 if (!processSanityChecksLocked(process)) {
21850                     continue;
21851                 }
21852                 try {
21853                     process.thread.startBinderTracking();
21854                 } catch (RemoteException e) {
21855                     Log.v(TAG, "Process disappared");
21856                 }
21857             }
21858             return true;
21859         }
21860     }
21861
21862     public boolean stopBinderTrackingAndDump(ParcelFileDescriptor fd) throws RemoteException {
21863         try {
21864             synchronized (this) {
21865                 mBinderTransactionTrackingEnabled = false;
21866                 // TODO: hijacking SET_ACTIVITY_WATCHER, but should be changed to its own
21867                 // permission (same as profileControl).
21868                 if (checkCallingPermission(android.Manifest.permission.SET_ACTIVITY_WATCHER)
21869                         != PackageManager.PERMISSION_GRANTED) {
21870                     throw new SecurityException("Requires permission "
21871                             + android.Manifest.permission.SET_ACTIVITY_WATCHER);
21872                 }
21873
21874                 if (fd == null) {
21875                     throw new IllegalArgumentException("null fd");
21876                 }
21877
21878                 PrintWriter pw = new FastPrintWriter(new FileOutputStream(fd.getFileDescriptor()));
21879                 pw.println("Binder transaction traces for all processes.\n");
21880                 for (ProcessRecord process : mLruProcesses) {
21881                     if (!processSanityChecksLocked(process)) {
21882                         continue;
21883                     }
21884
21885                     pw.println("Traces for process: " + process.processName);
21886                     pw.flush();
21887                     try {
21888                         TransferPipe tp = new TransferPipe();
21889                         try {
21890                             process.thread.stopBinderTrackingAndDump(
21891                                     tp.getWriteFd().getFileDescriptor());
21892                             tp.go(fd.getFileDescriptor());
21893                         } finally {
21894                             tp.kill();
21895                         }
21896                     } catch (IOException e) {
21897                         pw.println("Failure while dumping IPC traces from " + process +
21898                                 ".  Exception: " + e);
21899                         pw.flush();
21900                     } catch (RemoteException e) {
21901                         pw.println("Got a RemoteException while dumping IPC traces from " +
21902                                 process + ".  Exception: " + e);
21903                         pw.flush();
21904                     }
21905                 }
21906                 fd = null;
21907                 return true;
21908             }
21909         } finally {
21910             if (fd != null) {
21911                 try {
21912                     fd.close();
21913                 } catch (IOException e) {
21914                 }
21915             }
21916         }
21917     }
21918
21919     private final class LocalService extends ActivityManagerInternal {
21920         @Override
21921         public void grantUriPermissionFromIntent(int callingUid, String targetPkg, Intent intent,
21922                 int targetUserId) {
21923             synchronized (ActivityManagerService.this) {
21924                 ActivityManagerService.this.grantUriPermissionFromIntentLocked(callingUid,
21925                         targetPkg, intent, null, targetUserId);
21926             }
21927         }
21928
21929         @Override
21930         public String checkContentProviderAccess(String authority, int userId) {
21931             return ActivityManagerService.this.checkContentProviderAccess(authority, userId);
21932         }
21933
21934         @Override
21935         public void onWakefulnessChanged(int wakefulness) {
21936             ActivityManagerService.this.onWakefulnessChanged(wakefulness);
21937         }
21938
21939         @Override
21940         public int startIsolatedProcess(String entryPoint, String[] entryPointArgs,
21941                 String processName, String abiOverride, int uid, Runnable crashHandler) {
21942             return ActivityManagerService.this.startIsolatedProcess(entryPoint, entryPointArgs,
21943                     processName, abiOverride, uid, crashHandler);
21944         }
21945
21946         @Override
21947         public SleepToken acquireSleepToken(String tag) {
21948             Preconditions.checkNotNull(tag);
21949
21950             ComponentName requestedVrService = null;
21951             ComponentName callingVrActivity = null;
21952             int userId = -1;
21953             synchronized (ActivityManagerService.this) {
21954                 if (mFocusedActivity != null) {
21955                     requestedVrService = mFocusedActivity.requestedVrComponent;
21956                     callingVrActivity = mFocusedActivity.info.getComponentName();
21957                     userId = mFocusedActivity.userId;
21958                 }
21959             }
21960
21961             if (requestedVrService != null) {
21962                 applyVrMode(false, requestedVrService, userId, callingVrActivity, true);
21963             }
21964
21965             synchronized (ActivityManagerService.this) {
21966                 SleepTokenImpl token = new SleepTokenImpl(tag);
21967                 mSleepTokens.add(token);
21968                 updateSleepIfNeededLocked();
21969                 return token;
21970             }
21971         }
21972
21973         @Override
21974         public ComponentName getHomeActivityForUser(int userId) {
21975             synchronized (ActivityManagerService.this) {
21976                 ActivityRecord homeActivity = mStackSupervisor.getHomeActivityForUser(userId);
21977                 return homeActivity == null ? null : homeActivity.realActivity;
21978             }
21979         }
21980
21981         @Override
21982         public void onUserRemoved(int userId) {
21983             synchronized (ActivityManagerService.this) {
21984                 ActivityManagerService.this.onUserStoppedLocked(userId);
21985             }
21986         }
21987
21988         @Override
21989         public void onLocalVoiceInteractionStarted(IBinder activity,
21990                 IVoiceInteractionSession voiceSession, IVoiceInteractor voiceInteractor) {
21991             synchronized (ActivityManagerService.this) {
21992                 ActivityManagerService.this.onLocalVoiceInteractionStartedLocked(activity,
21993                         voiceSession, voiceInteractor);
21994             }
21995         }
21996
21997         @Override
21998         public void notifyStartingWindowDrawn() {
21999             synchronized (ActivityManagerService.this) {
22000                 mStackSupervisor.mActivityMetricsLogger.notifyStartingWindowDrawn();
22001             }
22002         }
22003
22004         @Override
22005         public void notifyAppTransitionStarting(int reason) {
22006             synchronized (ActivityManagerService.this) {
22007                 mStackSupervisor.mActivityMetricsLogger.notifyTransitionStarting(reason);
22008             }
22009         }
22010
22011         @Override
22012         public void notifyAppTransitionFinished() {
22013             synchronized (ActivityManagerService.this) {
22014                 mStackSupervisor.notifyAppTransitionDone();
22015             }
22016         }
22017
22018         @Override
22019         public void notifyAppTransitionCancelled() {
22020             synchronized (ActivityManagerService.this) {
22021                 mStackSupervisor.notifyAppTransitionDone();
22022             }
22023         }
22024
22025         @Override
22026         public List<IBinder> getTopVisibleActivities() {
22027             synchronized (ActivityManagerService.this) {
22028                 return mStackSupervisor.getTopVisibleActivities();
22029             }
22030         }
22031
22032         @Override
22033         public void notifyDockedStackMinimizedChanged(boolean minimized) {
22034             synchronized (ActivityManagerService.this) {
22035                 mStackSupervisor.setDockedStackMinimized(minimized);
22036             }
22037         }
22038
22039         @Override
22040         public void killForegroundAppsForUser(int userHandle) {
22041             synchronized (ActivityManagerService.this) {
22042                 final ArrayList<ProcessRecord> procs = new ArrayList<>();
22043                 final int NP = mProcessNames.getMap().size();
22044                 for (int ip = 0; ip < NP; ip++) {
22045                     final SparseArray<ProcessRecord> apps = mProcessNames.getMap().valueAt(ip);
22046                     final int NA = apps.size();
22047                     for (int ia = 0; ia < NA; ia++) {
22048                         final ProcessRecord app = apps.valueAt(ia);
22049                         if (app.persistent) {
22050                             // We don't kill persistent processes.
22051                             continue;
22052                         }
22053                         if (app.removed) {
22054                             procs.add(app);
22055                         } else if (app.userId == userHandle && app.foregroundActivities) {
22056                             app.removed = true;
22057                             procs.add(app);
22058                         }
22059                     }
22060                 }
22061
22062                 final int N = procs.size();
22063                 for (int i = 0; i < N; i++) {
22064                     removeProcessLocked(procs.get(i), false, true, "kill all fg");
22065                 }
22066             }
22067         }
22068
22069         @Override
22070         public void setPendingIntentWhitelistDuration(IIntentSender target, long duration) {
22071             if (!(target instanceof PendingIntentRecord)) {
22072                 Slog.w(TAG, "markAsSentFromNotification(): not a PendingIntentRecord: " + target);
22073                 return;
22074             }
22075             ((PendingIntentRecord) target).setWhitelistDuration(duration);
22076         }
22077
22078         @Override
22079         public void updatePersistentConfigurationForUser(@NonNull Configuration values,
22080                 int userId) {
22081             Preconditions.checkNotNull(values, "Configuration must not be null");
22082             Preconditions.checkArgumentNonnegative(userId, "userId " + userId + " not supported");
22083             synchronized (ActivityManagerService.this) {
22084                 updateConfigurationLocked(values, null, false, true, userId,
22085                         false /* deferResume */);
22086             }
22087         }
22088
22089         @Override
22090         public int startActivitiesAsPackage(String packageName, int userId, Intent[] intents,
22091                 Bundle bOptions) {
22092             Preconditions.checkNotNull(intents, "intents");
22093             final String[] resolvedTypes = new String[intents.length];
22094             for (int i = 0; i < intents.length; i++) {
22095                 resolvedTypes[i] = intents[i].resolveTypeIfNeeded(mContext.getContentResolver());
22096             }
22097
22098             // UID of the package on user userId.
22099             // "= 0" is needed because otherwise catch(RemoteException) would make it look like
22100             // packageUid may not be initialized.
22101             int packageUid = 0;
22102             try {
22103                 packageUid = AppGlobals.getPackageManager().getPackageUid(
22104                         packageName, PackageManager.MATCH_DEBUG_TRIAGED_MISSING, userId);
22105             } catch (RemoteException e) {
22106                 // Shouldn't happen.
22107             }
22108
22109             synchronized (ActivityManagerService.this) {
22110                 return startActivitiesInPackage(packageUid, packageName, intents, resolvedTypes,
22111                         /*resultTo*/ null, bOptions, userId);
22112             }
22113         }
22114
22115         @Override
22116         public int getUidProcessState(int uid) {
22117             return getUidState(uid);
22118         }
22119     }
22120
22121     private final class SleepTokenImpl extends SleepToken {
22122         private final String mTag;
22123         private final long mAcquireTime;
22124
22125         public SleepTokenImpl(String tag) {
22126             mTag = tag;
22127             mAcquireTime = SystemClock.uptimeMillis();
22128         }
22129
22130         @Override
22131         public void release() {
22132             synchronized (ActivityManagerService.this) {
22133                 if (mSleepTokens.remove(this)) {
22134                     updateSleepIfNeededLocked();
22135                 }
22136             }
22137         }
22138
22139         @Override
22140         public String toString() {
22141             return "{\"" + mTag + "\", acquire at " + TimeUtils.formatUptime(mAcquireTime) + "}";
22142         }
22143     }
22144
22145     /**
22146      * An implementation of IAppTask, that allows an app to manage its own tasks via
22147      * {@link android.app.ActivityManager.AppTask}.  We keep track of the callingUid to ensure that
22148      * only the process that calls getAppTasks() can call the AppTask methods.
22149      */
22150     class AppTaskImpl extends IAppTask.Stub {
22151         private int mTaskId;
22152         private int mCallingUid;
22153
22154         public AppTaskImpl(int taskId, int callingUid) {
22155             mTaskId = taskId;
22156             mCallingUid = callingUid;
22157         }
22158
22159         private void checkCaller() {
22160             if (mCallingUid != Binder.getCallingUid()) {
22161                 throw new SecurityException("Caller " + mCallingUid
22162                         + " does not match caller of getAppTasks(): " + Binder.getCallingUid());
22163             }
22164         }
22165
22166         @Override
22167         public void finishAndRemoveTask() {
22168             checkCaller();
22169
22170             synchronized (ActivityManagerService.this) {
22171                 long origId = Binder.clearCallingIdentity();
22172                 try {
22173                     // We remove the task from recents to preserve backwards
22174                     if (!removeTaskByIdLocked(mTaskId, false, REMOVE_FROM_RECENTS)) {
22175                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22176                     }
22177                 } finally {
22178                     Binder.restoreCallingIdentity(origId);
22179                 }
22180             }
22181         }
22182
22183         @Override
22184         public ActivityManager.RecentTaskInfo getTaskInfo() {
22185             checkCaller();
22186
22187             synchronized (ActivityManagerService.this) {
22188                 long origId = Binder.clearCallingIdentity();
22189                 try {
22190                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22191                     if (tr == null) {
22192                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22193                     }
22194                     return createRecentTaskInfoFromTaskRecord(tr);
22195                 } finally {
22196                     Binder.restoreCallingIdentity(origId);
22197                 }
22198             }
22199         }
22200
22201         @Override
22202         public void moveToFront() {
22203             checkCaller();
22204             // Will bring task to front if it already has a root activity.
22205             final long origId = Binder.clearCallingIdentity();
22206             try {
22207                 synchronized (this) {
22208                     mStackSupervisor.startActivityFromRecentsInner(mTaskId, null);
22209                 }
22210             } finally {
22211                 Binder.restoreCallingIdentity(origId);
22212             }
22213         }
22214
22215         @Override
22216         public int startActivity(IBinder whoThread, String callingPackage,
22217                 Intent intent, String resolvedType, Bundle bOptions) {
22218             checkCaller();
22219
22220             int callingUser = UserHandle.getCallingUserId();
22221             TaskRecord tr;
22222             IApplicationThread appThread;
22223             synchronized (ActivityManagerService.this) {
22224                 tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22225                 if (tr == null) {
22226                     throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22227                 }
22228                 appThread = ApplicationThreadNative.asInterface(whoThread);
22229                 if (appThread == null) {
22230                     throw new IllegalArgumentException("Bad app thread " + appThread);
22231                 }
22232             }
22233             return mActivityStarter.startActivityMayWait(appThread, -1, callingPackage, intent,
22234                     resolvedType, null, null, null, null, 0, 0, null, null,
22235                     null, bOptions, false, callingUser, null, tr);
22236         }
22237
22238         @Override
22239         public void setExcludeFromRecents(boolean exclude) {
22240             checkCaller();
22241
22242             synchronized (ActivityManagerService.this) {
22243                 long origId = Binder.clearCallingIdentity();
22244                 try {
22245                     TaskRecord tr = mStackSupervisor.anyTaskForIdLocked(mTaskId);
22246                     if (tr == null) {
22247                         throw new IllegalArgumentException("Unable to find task ID " + mTaskId);
22248                     }
22249                     Intent intent = tr.getBaseIntent();
22250                     if (exclude) {
22251                         intent.addFlags(Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22252                     } else {
22253                         intent.setFlags(intent.getFlags()
22254                                 & ~Intent.FLAG_ACTIVITY_EXCLUDE_FROM_RECENTS);
22255                     }
22256                 } finally {
22257                     Binder.restoreCallingIdentity(origId);
22258                 }
22259             }
22260         }
22261     }
22262
22263     /**
22264      * Kill processes for the user with id userId and that depend on the package named packageName
22265      */
22266     @Override
22267     public void killPackageDependents(String packageName, int userId) {
22268         enforceCallingPermission(android.Manifest.permission.KILL_UID, "killPackageDependents()");
22269         if (packageName == null) {
22270             throw new NullPointerException(
22271                     "Cannot kill the dependents of a package without its name.");
22272         }
22273
22274         long callingId = Binder.clearCallingIdentity();
22275         IPackageManager pm = AppGlobals.getPackageManager();
22276         int pkgUid = -1;
22277         try {
22278             pkgUid = pm.getPackageUid(packageName, MATCH_DEBUG_TRIAGED_MISSING, userId);
22279         } catch (RemoteException e) {
22280         }
22281         if (userId != UserHandle.USER_ALL && pkgUid == -1) {
22282             throw new IllegalArgumentException(
22283                     "Cannot kill dependents of non-existing package " + packageName);
22284         }
22285         try {
22286             synchronized(this) {
22287                 killPackageProcessesLocked(packageName, UserHandle.getAppId(pkgUid), userId,
22288                         ProcessList.FOREGROUND_APP_ADJ, false, true, true, false,
22289                         "dep: " + packageName);
22290             }
22291         } finally {
22292             Binder.restoreCallingIdentity(callingId);
22293         }
22294     }
22295
22296     @Override
22297     public boolean canBypassWorkChallenge(PendingIntent intent) throws RemoteException {
22298         final int userId = intent.getCreatorUserHandle().getIdentifier();
22299         if (!mUserController.isUserRunningLocked(userId, ActivityManager.FLAG_AND_LOCKED)) {
22300             return false;
22301         }
22302         IIntentSender target = intent.getTarget();
22303         if (!(target instanceof PendingIntentRecord)) {
22304             return false;
22305         }
22306         final PendingIntentRecord record = (PendingIntentRecord) target;
22307         final ResolveInfo rInfo = mStackSupervisor.resolveIntent(record.key.requestIntent,
22308                 record.key.requestResolvedType, userId, PackageManager.MATCH_DIRECT_BOOT_AWARE);
22309         // For direct boot aware activities, they can be shown without triggering a work challenge
22310         // before the profile user is unlocked.
22311         return rInfo != null && rInfo.activityInfo != null;
22312     }
22313 }